Explore how to generate a pseudo-random noun, fully on-chain, with just two contract calls.
The traits of nouns are determined by a Seed
. To generate an on-chain image of a noun, we will first generate a seed using the NounSeeder
contract. Once we have our seed, we will then generate our noun image using the NounsDescriptor
contract.
The [NounsSeeder](<https://etherscan.io/address/0xCC8a0FB5ab3C7132c1b2A0109142Fb112c4Ce515#code>)
contract is in charge of generating Noun seeds. The contract has a generateSeed
function that accepts two arguments: nounId
and INounsDescriptor
.
nounId
can be any valid uint256
.INounsDescriptor
is the address
of the NounDescriptor
contract.function generateSeed(uint256 nounId, INounsDescriptor descriptor) external view returns (Seed memory);
The Seed
is a list of part ids that determine the noun traits. It can be randomly generated using the NounSeeder
contract or specified directly if you know which parts you want. Pseudo-random generation happens using the pending block's blockhash
and passed in nounId
.
A successful call will return a Seed
with random traits:
struct Seed {
uint48 background;
uint48 body;
uint48 accessory;
uint48 head;
uint48 glasses;
}
Using your favorite web3 library, call the NounSeeder
contract passing an arbitrary nounId
and the NounDescriptor
address as arguments.
const nounId = 1234;
const nounDescriptor = "0x0Cfdb3Ba1694c2bb2CFACB0339ad7b1Ae5932B63";
**const seed = await nounSeederContract.generateSeed(nounId, nounDescriptor);**
<aside>
💡 To make sure we get different Seed
on every call, be sure to change the nounId
on e every call as the blockhash
will remain the same while the block is being mined (~15s).
</aside>
The [NounsDescriptor](<https://etherscan.io/address/0x0Cfdb3Ba1694c2bb2CFACB0339ad7b1Ae5932B63#code>)
contract is used to store/render Noun artwork. We will use it to generate an .svg
image from our Seed
.
function generateSVGImage(INounsSeeder.Seed memory seed) external view returns (string memory);
Using our Seed
from step one, we can call the function as follows:
const nounId = 1234;
const nounDescriptor = "0x0Cfdb3Ba1694c2bb2CFACB0339ad7b1Ae5932B63";
const seed = await nounSeederContract.generateSeed(nounId, nounDescriptor);
**const svg = await nounsDescriptorContract.generateSVGImage(seed)**
A successful response will return a base64
encoded string representing the .svg
image of the noun determined by the Seed
: