v3
The full v3 NFT program is shown below and fully annotated. The code is explained so that you may understand and modify this program for your own use.
// The 'leo_nft' program.
data1: u128, // Part 1 of the image data -- i.e., a way to link this nft to image or aws
data2: u128,
}
// base uri ascii bits. Include as many data pieces as necessary to encapsulate the uri. Padded with 0s at the end.
data0: u128, // Part 1 of the base uri in bits. Bits should be the representation of the hexadecimal bytes for the ASCII text of the URL
data1: u128,
data2: u128,
data3: u128
}
data: u128 // The sybmol's ascii text represented in bits, and the u128 value of the bitstring.
}
private owner: address,
private data: TokenId,
private edition: scalar, // which edition of the nft this particular one is -- will be 0 for unique NFTs
}
// a way to prove ownership of an nft privately
private owner: address,
private nft_owner: address,
private data: TokenId,
private edition: scalar, // which edition of the nft this particular one is -- will be 0 for unique NFTs
}
public total: u128,
public symbol: u128,
public base_uri: BaseURI,
) {
}
finalize initialize_collection(
public total: u128,
public symbol: u128,
public base_uri: BaseURI,
) {
// Ensure initialize cannot be called twice!
let is_initialized: u128 = settings.get_or_use(0u8, 0u128);
assert_eq(is_initialized, 0u128);
settings.set(1u8, total); // Number of total NFTs (first-editions) that can be minted
settings.set(2u8, 0u128); // Is the mint live
settings.set(3u8, symbol); // Symbol for the NFT
settings.set(4u8, base_uri.data0); // Base URI for NFT
settings.set(5u8, base_uri.data1);
settings.set(6u8, base_uri.data2);
settings.set(7u8, base_uri.data3);
settings.set(8u8, 0u128); // Block height for mint to go live (given mint is live setting)
settings.set(9u8, 0u128); // If collection is frozen
}
// Load the data into the mapping
// Enables someone to mint an NFT with provided image data
transition add_nft(public tokenId: TokenId, public edition: scalar) {
assert_eq(self.caller, aleo1gy3d0s00s2k7rmgqznnx2q8htmjm2p5rk8q40u5yklqhe44utvys0dmzdy);
let tokenEditionHash: field = BHP256::commit_to_field(tokenHash, edition);
return then finalize(tokenEditionHash);
}
finalize add_nft(public tokenEditionHash: field) {
let frozen: u128 = settings.get(9u8);
assert_eq(frozen, 0u128);
let existing_editions: u8 = nft_totals.get_or_use(tokenEditionHash, 255u8);
assert_eq(existing_editions, 255u8);
nft_totals.set(tokenEditionHash, 1u8);
// Reduce the amount of total nfts that can be minted
let remaining: u128 = settings.get(1u8);
settings.set(1u8, remaining - 1u128);
}
transition add_minter(public minter: address, public amount: u8) {
assert_eq(self.caller, aleo1gy3d0s00s2k7rmgqznnx2q8htmjm2p5rk8q40u5yklqhe44utvys0dmzdy);
return then finalize(minter, amount);
}
finalize add_minter(
public minter: address,
public amount: u8
)
{
let frozen: u128 = settings.get(9u8);
assert_eq(frozen, 0u128);
whitelist.set(minter, amount);
}
transition set_mint_status(public status: u128) {
assert_eq(self.caller, aleo1gy3d0s00s2k7rmgqznnx2q8htmjm2p5rk8q40u5yklqhe44utvys0dmzdy);
return then finalize(status);
}
finalize set_mint_status(public status: u128) {
let frozen: u128 = settings.get(9u8);
assert_eq(frozen, 0u128);
settings.set(2u8, status);
}
transition set_mint_block(public mint_block: u128) {
assert_eq(self.caller, aleo1gy3d0s00s2k7rmgqznnx2q8htmjm2p5rk8q40u5yklqhe44utvys0dmzdy);
return then finalize(mint_block);
}
finalize set_mint_block(public mint_block: u128) {
let frozen: u128 = settings.get(9u8);
assert_eq(frozen, 0u128);
settings.set(8u8, mint_block);
}
transition update_symbol(public symbol: u128) {
assert_eq(self.caller, aleo1gy3d0s00s2k7rmgqznnx2q8htmjm2p5rk8q40u5yklqhe44utvys0dmzdy);
return then finalize(symbol);
}
finalize update_symbol(public symbol: u128) {
let frozen: u128 = settings.get(9u8);
assert_eq(frozen, 0u128);
settings.set(3u8, symbol);
}
transition update_base_uri(public base_uri: BaseURI) {
assert_eq(self.caller, aleo1gy3d0s00s2k7rmgqznnx2q8htmjm2p5rk8q40u5yklqhe44utvys0dmzdy);
return then finalize(base_uri);
}
finalize update_base_uri(public base_uri: BaseURI) {
let frozen: u128 = settings.get(9u8);
assert_eq(frozen, 0u128);
settings.set(4u8, base_uri.data0); // Base URI for NFT
settings.set(5u8, base_uri.data1);
settings.set(6u8, base_uri.data2);
settings.set(7u8, base_uri.data3);
}
transition freeze() {
assert_eq(self.caller, aleo1gy3d0s00s2k7rmgqznnx2q8htmjm2p5rk8q40u5yklqhe44utvys0dmzdy);
return then finalize();
}
finalize freeze() {
let frozen: u128 = settings.get(9u8);
assert_eq(frozen, 0u128);
settings.set(9u8, 1u128);
}
let tokenHash: field = BHP256::hash_to_field(tokenId);
let tokenEditionHash: field = BHP256::commit_to_field(tokenHash, edition);
return NFT {
owner: self.caller,
data: tokenId,
edition
} then finalize(self.caller, tokenEditionHash);
}
finalize mint(public owner: address, public tokenEditionHash: field) {
// Ensure mint is live
let is_live: u128 = settings.get(2u8);
assert_eq(is_live, 1u128);
// Ensure owner can mint and decrease remaining mints (overflow protection)
let remaining: u8 = whitelist.get(owner);
whitelist.set(owner, remaining - 1u8);
// Ensure more editions can be made and decrease remaining editions (overflow protection)
let amount: u8 = nft_totals.get(tokenEditionHash);
nft_totals.set(tokenEditionHash, amount - 1u8);
}
transition transfer_private(
nft: NFT,
private receiver: address
) -> NFT
{
return NFT {
owner: receiver,
data: nft.data,
edition: nft.edition
};
}
transition transfer_public(
private receiver: address,
private data: TokenId,
private edition: scalar
)
{
let tokenHash: field = BHP256::hash_to_field(data);
let tokenEditionHash: field = BHP256::commit_to_field(tokenHash, edition);
let caller: address = self.caller;
return then finalize(receiver, tokenEditionHash, caller);
}
finalize transfer_public(
public receiver: address,
public tokenEditionHash: field,
public caller: address
)
{
assert_eq(caller, nft_owners.get(tokenEditionHash));
nft_owners.set(tokenEditionHash, receiver);
}
transition convert_private_to_public(
nft: NFT
)
{
let tokenHash: field = BHP256::hash_to_field(nft.data);
let tokenEditionHash: field = BHP256::commit_to_field(tokenHash, nft.edition);
return then finalize(nft.owner, tokenEditionHash);
}
finalize convert_private_to_public(
public owner: address,
public tokenEditionHash: field
)
{
nft_owners.set(tokenEditionHash, owner);
}
transition convert_public_to_private(
private owner: address,
private data: TokenId,
private edition: scalar
) -> NFT
{
assert_eq(owner, self.caller);
let tokenHash: field = BHP256::hash_to_field(data);
let tokenEditionHash: field = BHP256::commit_to_field(tokenHash, edition);
return NFT {
owner,
data,
edition
} then finalize(owner, tokenEditionHash);
}
finalize convert_public_to_private(
public owner: address,
public tokenEditionHash: field
)
{
assert_eq(owner, nft_owners.get(tokenEditionHash));
// mapping::remove is not implemented yet, so instead we set the owner to be a dummy address that cannot publicly transfer or convert to private
nft_owners.set(tokenEditionHash, aleo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc);
}
return (
NFT {
owner: nft.owner,
data: nft.data,
edition: nft.edition
},
NFT_ownership {
owner: prove_to,
nft_owner: nft.owner,
data: nft.data,
edition: nft.edition
}
);
}
}
Last updated