Explore how to generate a pseudo-random noun, fully on-chain, with just two contract calls.

Overview

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.

Generate a Seed

The NounsSeeder contract is in charge of generating Noun seeds. The contract has a generateSeed function that accepts two arguments: nounId and INounsDescriptor .

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>

Generate the Noun image

The NounsDescriptor 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: