Token Metadata

Token metadata defines the core characteristics and identity of an OP-20 token. These values are set during contract deployment via the instantiate() method and provide essential information about the token's configuration, supply constraints, and cryptographic domain.

OP-20 Metadata Implementation

The following metadata are part of the OP-20 standard and their implementation is mandatory for token contracts:

  • name
  • symbol
  • icon
  • decimals
  • totalSupply
  • domainSeparator

The OP20 base class implements all mandatory metadata properties and exposes the following additional property:

  • maximumSupply

Mandatory properties can be retrieved individually or collectively using the metadata() method. Custom properties must be accessed through their individual methods.

OP20 classassemblyscript
abstract class OP20 extends ReentrancyGuard implements IOP20 {
    // Mandatory in the OP-20 standard
    public name(_: Calldata): BytesWriter;
    public symbol(_: Calldata): BytesWriter;
    public icon(_: Calldata): BytesWriter;
    public decimals(_: Calldata): BytesWriter;
    public totalSupply(_: Calldata): BytesWriter;
    public domainSeparator(_: Calldata): BytesWriter;
    public metadata(_: Calldata): BytesWriter;
    
    // Custom to the OP20 implementation
    public maximumSupply(_: Calldata): BytesWriter;
    ...
}

Using Metadata Methods in a Contract

Individual call

The following example demonstrates how to call the name() method to obtain the token name:
Get token name exampleassemblyscript
import { u256 } from '@btc-vision/as-bignum/assembly';
import { 
    Address,
    Blockchain, 
    BytesWriter,
    ReentrancyGuard,
    SELECTOR_BYTE_LENGTH,
    NAME_SELECTOR
} from '@btc-vision/btc-runtime/runtime';

@final
export class MyContract extends ReentrancyGuard {
    public constructor() {
        super();
    }
    
    ...

    // Call the token contract to get the token name.
    private getTokenName(token: Address) : void{
        // Encode name Calldata
        // 1st parameter: selector (method to call->name)
        const calldata = new BytesWriter(SELECTOR_BYTE_LENGTH);

        calldata.writeSelector(NAME_SELECTOR);

        const response = Blockchain.call(token, calldata);

        if (response.data.byteLength == 0){
            thow new Revert('Invalid response from name.');
        }
        
        const name = response.data.readStringWithLength();
    }
}

Single Call/Get All

The following example demonstrates how to call the metadata() method to obtain all base metadata at once:
Single call/get all exampleassemblyscript
import { u256 } from '@btc-vision/as-bignum/assembly';
import { 
    Address,
    Blockchain, 
    BytesWriter,
    ReentrancyGuard,
    SELECTOR_BYTE_LENGTH,
    METADATA_SELECTOR
} from '@btc-vision/btc-runtime/runtime';

@final
export class MyContract extends ReentrancyGuard {
    public constructor() {
        super();
    }
    
    ...

    // Call the token contract to get all the metadata in a single call.
    private getTokenMetadata(token: Address) : void{
        // Encode name Calldata
        // 1st parameter: selector (method to call->metadata)
        const calldata = new BytesWriter(SELECTOR_BYTE_LENGTH);

        calldata.writeSelector(METADATA_SELECTOR);

        const response = Blockchain.call(token, calldata);

        if (response.data.byteLength == 0){
            thow new Revert('Invalid response from metadata.');
        }
        
        const name = response.data.readStringWithLength();
        const symbol = response.data.readStringWithLength();
        const icon = response.data.readStringWithLength();
        const decimals = response.data.readU8();
        const totalSupply = response.data.readU256();
        const domainSeparator = response.data.readBytesWithLength();
    }
}