Returns the token name.
This is a read-only method.
The BytesWriter class encodes calldata parameters for contract calls, while the response data can be decoded using corresponding read methods. The calldata is constructed by writing the function selector followed by each parameter in order. After executing the call, the response is decoded by reading values in the same sequence as the contract returns them.
// How to encode the Calldata parameters
// 1st parameter: selector (method to call)
// 2nd parameter: address1
// 3rd parameter: amount1
const calldata = new BytesWriter(SELECTOR_BYTE_LENGTH +
ADDRESS_BYTE_LENGTH +
U256_BYTE_LENGTH);
calldata.writeSelector('FUNCTION SELECTOR HERE');
calldata.writeAddress(address1);
calldata.writeU256(amount1);
// How to decode BytesWriter return values
const response = Blockchain.call(token, calldata);
if (response.data.byteLength != 0){
thow new Revert('Invalid response.');
}
// Decode response
const value = response.data.readU256();
const name = response.data.readStringWithLength();The OP20 class is the OP_NET concrete implementation of the OP_20 standard. It implements the IOP20 interface and extends ReentrancyGuard, which provides both OP_NET base class inheritance and built-in reentrancy attack protection.
Protected methods can be overridden to implement custom logic or extend the default behavior, providing flexibility for specialized token implementations.
abstract class OP20 extends ReentrancyGuard implements IOP20 {
public name(_: Calldata): BytesWriter;
public symbol(_: Calldata): BytesWriter;
public icon(_: Calldata): BytesWriter;
public decimals(_: Calldata): BytesWriter;
public totalSupply(_: Calldata): BytesWriter;
public maximumSupply(_: Calldata): BytesWriter;
public metadata(_: Calldata): BytesWriter;
public domainSeparator(_: Calldata): BytesWriter;
public balanceOf(calldata: Calldata): BytesWriter;
public nonceOf(calldata: Calldata): BytesWriter;
public allowance(calldata: Calldata): BytesWriter;
public safeTransfer(calldata: Calldata): BytesWriter;
public safeTransferFrom(calldata: Calldata): BytesWriter;
public transfer(calldata: Calldata): BytesWriter;
public transferFrom(calldata: Calldata): BytesWriter;
public burn(calldata: Calldata): BytesWriter;
public increaseAllowance(calldata: Calldata): BytesWriter;
public decreaseAllowance(calldata: Calldata): BytesWriter;
public increaseAllowanceBySignature(calldata: Calldata): BytesWriter;
public decreaseAllowanceBySignature(calldata: Calldata): BytesWriter;
// Used for token deployments
public instantiate(params: OP20InitParameters, skipDeployerVerification: boolean = false): void;
// Overrides
protected _balanceOf(owner: Address): u256;
protected _allowance(owner: Address, spender: Address): u256;
protected _safeTransfer(from: Address, to: Address, amount: u256, data: Uint8Array): void;
protected _transfer(from: Address, to: Address, amount: u256): void;
protected _spendAllowance(owner: Address, spender: Address, amount: u256): void;
protected _callOnOP20Received( from: Address, to: Address, amount: u256,data: Uint8Array): void;
protected _increaseAllowance(owner: Address, spender: Address, amount: u256): void;
protected _decreaseAllowance(owner: Address, spender: Address, amount: u256): void;
protected _increaseAllowanceBySignature(owner: Address,spender: Address,amount: u256,deadline: u64,signature: Uint8Array): void;
protected _decreaseAllowanceBySignature(owner: Address, spender: Address, amount: u256, deadline: u64, signature: Uint8Array): void;
protected _verifySignature(typeHash: u8[], owner: Address, spender: Address, amount: u256, deadline: u64, signature: Uint8Array): void;
protected _buildDomainSeparator(): Uint8Array;
protected _mint(to: Address, amount: u256): void;
protected _burn(from: Address, amount: u256): void;
}public name(_: Calldata): BytesWriterReturns the token name.
This is a read-only method.
A BytesWriter stream with the following structure:
| Name | Type | Description |
|---|---|---|
| name | string (with length) | Token name. |
public symbol(_: Calldata): BytesWriterReturns the token symbol.
This is a read-only method.
A BytesWriter stream with the following structure:
| Name | Type | Description |
|---|---|---|
| symbol | string (with length) | Token symbol. |
public icon(_: Calldata): BytesWriterReturns the token's icon URL (http(s) or ipfs) for wallet/UI display.
This is a read-only method.
A BytesWriter stream with the following structure:
| Name | Type | Description |
|---|---|---|
| icon | string (with length) | Icon URL. |
public decimals(_: Calldata): BytesWriterReturns the number of decimal places used by the token. Valid range: 0-32. A value of 0 creates indivisible tokens.
This is a read-only method.
A BytesWriter stream with the following structure:
| Name | Type | Description |
|---|---|---|
| decimals | u8 | Number of decimals. |
public totalSupply(_: Calldata): BytesWriterReturns the current circulating amount of tokens.
This is a read-only method.
A BytesWriter stream with the following structure:
| Name | Type | Description |
|---|---|---|
| totalSupply | u256 | Current total supply. |
public maximumSupply(_: Calldata): BytesWriterReturns the maximum number of tokens that can exists.
This is a read-only method.
A BytesWriter stream with the following structure:
| Name | Type | Description |
|---|---|---|
| maximumSupply | u256 | Maximum supply cap. |
public metadata(_: Calldata): BytesWriterGet all token metadata in a single call.
This is a read-only method.
A BytesWriter stream with the following structure:
| Name | Type | Description |
|---|---|---|
| name | string (with length) | Token name. |
| symbol | string (with length) | Token symbol. |
| icon | string (with length) | Icon URL. |
| decimals | u8 | Number of decimals. |
| totalSupply | u256 | Current total supply. |
| domainSeparator | u8[] | 32-byte domain separator hash. |
public domainSeparator(_: Calldata): BytesWriterReturns a SHA-256 hash representing the unique domain separator. The hash must be derived from the OP712Domain structure.
Calls the protected _buildDomainSeparator() method, which provides the default implementation.
This is a read-only method.
A BytesWriter stream with the following structure:
| Name | Type | Description |
|---|---|---|
| domainSeparator | u8[32] | 32-byte domain separator hash. |
public balanceOf(calldata: Calldata): BytesWriterReturns the actual token balance for an address. Non-existent addresses return 0.
Calls the protected _balanceOf() method, which provides the default implementation.
This is a read-only method.
| Name | Type | Required | Description |
|---|---|---|---|
| owner | Address | - |
A BytesWriter stream with the following structure:
| Name | Type | Description |
|---|---|---|
| balance | u256 | Balance. |
public nonceOf(calldata: Calldata): BytesWriterReturns the current nonce for an address. Non-existent addresses return 0.
This is a read-only method.
| Name | Type | Required | Description |
|---|---|---|---|
| owner | Address | - |
A BytesWriter stream with the following structure:
| Name | Type | Description |
|---|---|---|
| nonce | u256 | Current nonce. |
public allowance(calldata: Calldata): BytesWriterReturns the "spender's" remaining allowance from the "owner's" account. Non-existent addresses return 0.
Calls the protected _allowance() method, which provides the default implementation.
This is a read-only method.
| Name | Type | Required | Description |
|---|---|---|---|
| owner | Address | - | |
| spender | Address | - |
A BytesWriter stream with the following structure:
| Name | Type | Description |
|---|---|---|
| remaining | u256 | Remaining allowance. |
public safeTransfer(calldata: Calldata): BytesWriterTransfers amount of tokens from the caller's account to the to address with delivery confirmation for contract recipients. An arbitrary data payload can be specified.
The following validations are performed:
Calls the protected _safeTransfer() method, which provides the default implementation.
| Name | Type | Required | Description |
|---|---|---|---|
| to | Address | - | |
| amount | u256 | - | |
| data? | u8[] | - | Optional data. |
A BytesWriter stream with the following structure:
| Name | Type | Description |
|---|---|---|
| - | BytesWriter | A 0 length BytesWriter object. |
| Type | Description |
|---|---|
| Transferred | Emits a Transferred event. |
public safeTransferFrom(calldata: Calldata): BytesWriterTransfers amount of tokens from the from address to the to address with delivery confirmation for contract recipients. An arbitrary data payload can be specified.
The following validations/actions are performed:
Calls the protected _spendAllowance() and _safeTransfer() methods, which provides the default implementation.
| Name | Type | Required | Description |
|---|---|---|---|
| from | Address | - | |
| to | Address | - | |
| amount | u256 | - | |
| data? | u8[] | - | Optional data. |
A BytesWriter stream with the following structure:
| Name | Type | Description |
|---|---|---|
| - | BytesWriter | A 0 length BytesWriter object. |
| Type | Description |
|---|---|
| Transferred | Emits a Transferred event. |
public transfer(calldata: Calldata): BytesWriterTransfers amount of tokens from the caller's account to the to address.
The following validations are performed:
Calls the protected _transfer() method, which provides the default implementation.
| Name | Type | Required | Description |
|---|---|---|---|
| to | Address | - | |
| amount | u256 | - |
A BytesWriter stream with the following structure:
| Name | Type | Description |
|---|---|---|
| - | BytesWriter | A 0 length BytesWriter object. |
| Type | Description |
|---|---|
| Transferred | Emits a Transferred event. |
public transferFrom(calldata: Calldata): BytesWriterTransfers amount of tokens from the from address to the to address.
The following validations/actions are performed:
Calls the protected _spendAllowance() and _transfer() methods, which provides the default implementation.
| Name | Type | Required | Description |
|---|---|---|---|
| from | Address | - | |
| to | Address | - | |
| amount | u256 | - |
A BytesWriter stream with the following structure:
| Name | Type | Description |
|---|---|---|
| - | BytesWriter | A 0 length BytesWriter object. |
| Type | Description |
|---|---|
| Transferred | Emits a Transferred event. |
public burn(calldata: Calldata): BytesWriterAtomically subtract amount from the caller’s balance and reduce totalSupply by the same amount.
The following validations are performed:
Calls the protected _burn() method, which provides the default implementation.
| Name | Type | Required | Description |
|---|---|---|---|
| amount | u256 | - |
A BytesWriter stream with the following structure:
| Name | Type | Description |
|---|---|---|
| - | BytesWriter | A 0 length BytesWriter object. |
| Type | Description |
|---|---|
| Burned | Emits a Burned event. |
public increaseAllowance(calldata: Calldata): BytesWriterAtomically increase spender allowance permission on the owner's account for the specified amount.
The following validations/actions are performed:
Calls the protected _increaseAllowance() method, which provides the default implementation.
| Name | Type | Required | Description |
|---|---|---|---|
| spender | Address | - | |
| amount | u256 | - |
A BytesWriter stream with the following structure:
| Name | Type | Description |
|---|---|---|
| - | BytesWriter | A 0 length BytesWriter object. |
| Type | Description |
|---|---|
| Approved | Emits an Approved event. |
public decreaseAllowance(calldata: Calldata): BytesWriterAtomically decrease spender allowance permission on the owner's account for the specified amounts.
The following validations/actions are performed:
Calls the protected _decreaseAllowance() method, which provides the default implementation.
| Name | Type | Required | Description |
|---|---|---|---|
| spender | Address | - | |
| amount | u256 | - |
A BytesWriter stream with the following structure:
| Name | Type | Description |
|---|---|---|
| - | BytesWriter | A 0 length BytesWriter object. |
| Type | Description |
|---|---|
| Approved | Emits an Approved event. |
public increaseAllowanceBySignature(calldata: Calldata): BytesWriterAtomically increase spender allowance off-chain on the owner's account for the specified amount.
The following validations/actions are performed:
Calls the protected _increaseAllowanceBySignature() method, which provides the default implementation.
| Name | Type | Required | Description |
|---|---|---|---|
| owner | Address | - | |
| spender | Address | - | |
| amount | u256 | - | |
| deadline | u64 | - | |
| signature | u8[] | - |
A BytesWriter stream with the following structure:
| Name | Type | Description |
|---|---|---|
| - | BytesWriter | A 0 length BytesWriter object. |
| Type | Description |
|---|---|
| Approved | Emits an Approved event. |
public decreaseAllowanceBySignature(calldata: Calldata): BytesWriterAtomically decrease spender allowance off-chain on the owner's account for the specified amount.
The following validations/actions are performed:
Calls the protected _decreaseAllowanceBySignature() method, which provides the default implementation.
| Name | Type | Required | Description |
|---|---|---|---|
| owner | Address | - | |
| spender | Address | - | |
| amount | u256 | - | |
| deadline | u64 | - | |
| signature | u8[] | - |
A BytesWriter stream with the following structure:
| Name | Type | Description |
|---|---|---|
| - | BytesWriter | A 0 length BytesWriter object. |
| Type | Description |
|---|---|
| Approved | Emits an Approved event. |
public instantiate(params: OP20InitParameters, skipDeployerVerification: boolean = false): voidInitialize the token metadata only once, immediately after deployment. After initialization, these values are immutable.
By default only the deployer may initialize. If deployer verification is skipped, a designated non-deployer may perform this one-time initialization.
| Name | Type | Required | Description |
|---|---|---|---|
| params | OP20InitParameters | - | |
| skipDeployerVerification | boolean | - | default to false. |
protected _balanceOf(owner: Address): u256Checks the balance map for the given owner address and returns the current balance, or 0 if the owner is not found.
| Name | Type | Required | Description |
|---|---|---|---|
| owner | Address | - |
| Name | Type | Description |
|---|---|---|
| balance | u256 | The current balance. |
protected _allowance(owner: Address, spender: Address): u256Checks the allowance map for the given owner and spender addresses and returns the remaining allowance, or 0 if none is set.
| Name | Type | Required | Description |
|---|---|---|---|
| owner | Address | - | The owner address to look from. |
| spender | Address | - | The spender address to look for. |
| Name | Type | Description |
|---|---|---|
| allowance | u256 | The current allowance, or 0 if none is set. |
protected _safeTransfer(from: Address, to: Address, amount: u256, data: Uint8Array): voidPerforms the actual safe transfer operation for the specified amount from the from address to the to address:
| Name | Type | Required | Description |
|---|---|---|---|
| from | Address | - | |
| to | Address | - | |
| amount | u256 | - | |
| data | Uint8Array - Optional data. | - |
protected _transfer(from: Address, to: Address, amount: u256): voidPerforms the actual transfer operation for the specified amount from the from address to the to address:
| Name | Type | Required | Description |
|---|---|---|---|
| from | Address | - | |
| to | Address | - | |
| amount | u256 | - |
protected _spendAllowance(owner: Address, spender: Address, amount: u256): voidSpends the given amount by reducing the available allowance from the allowance map:
| Name | Type | Required | Description |
|---|---|---|---|
| owner | Address | - | |
| spender | Address | - | |
| amount | u256 | - |
protected _callOnOP20Received(from: Address, to: Address, amount: u256, data: Uint8Array): voidCalls onOP20Received on the recipient contract with calldata conforming to the method specification. The method reverts:
| Name | Type | Required | Description |
|---|---|---|---|
| from | Address | - | |
| to | Address | - | |
| amount | u256 | - | |
| data | Uin8Array | - | Optional data. |
protected _increaseAllowance(owner: Address, spender: Address, amount: u256): voidPerforms the actual allowance increase operation for the specified amount:
| Name | Type | Required | Description |
|---|---|---|---|
| owner | Address | - | |
| spender | Address | - | |
| amount | u256 | - |
protected _decreaseAllowance(owner: Address, spender: Address, amount: u256): voidPerforms the actual allowance decrease operation for the specified amount:
| Name | Type | Required | Description |
|---|---|---|---|
| owner | Address | - | |
| spender | Address | - | |
| amount | u256 | - |
protected _increaseAllowanceBySignature(owner: Address, spender: Address, amount: u256, deadline: u64, signature: Uint8Array): voidPerforms the actual signed allowance increase operation:
| Name | Type | Required | Description |
|---|---|---|---|
| owner | Address | - | |
| spender | Address | - | |
| amount | u256 | - | |
| deadline | u64 | - | |
| signature | Uin8Array | - |
protected _decreaseAllowanceBySignature(owner: Address, spender: Address, amount: u256, deadline: u64, signature: Uint8Array): voidPerforms the actual signed allowance decrease operation:
| Name | Type | Required | Description |
|---|---|---|---|
| owner | Address | - | |
| spender | Address | - | |
| amount | u256 | - | |
| deadline | u64 | - | |
| signature | Uin8Array | - |
protected _verifySignature(typeHash: u8[], owner: Address, spender: Address, amount: u256, deadline: u64, signature: Uint8Array): voidValidates the signature and increments the owner's nonce on success:
| Name | Type | Required | Description |
|---|---|---|---|
| typeHash | u8[] | - | The operation type hash. |
| owner | Address | - | |
| spender | Address | - | |
| amount | u256 | - | |
| deadline | u64 | - | |
| signature | Uint8Array | - |
protected _buildDomainSeparator(): Uint8ArrayConstructs the domain separator buffer compliant with the OP712Domain structure, which is then used to generate the SHA-256 hash.
| Name | Type | Description |
|---|---|---|
| domainSeparator | Uint8Array. (192 bytes) | EIP-712 domain separator. |
protected _mint(to: Address, amount: u256): voidMints new tokens to the specified address:
| Name | Type | Required | Description |
|---|---|---|---|
| to | Address | - | |
| amount | u256 | - |
protected _burn(from: Address, amount: u256): voidBurns existing tokens from the specified address:
| Name | Type | Required | Description |
|---|---|---|---|
| from | Address | - | |
| amount | u256 | - |
The OP20 class emits the three OP_20 standard events: Approved, Burned, and Transferred.
Additionally, the OP20 class emits a Minted event, which is specific to this implementation and is implemented by the OP20MintedEvent class.
class OP20ApprovedEvent extends NetEvent {
constructor(owner: Address, spender: Address, amount: u256);
}constructor(owner: Address, spender: Address, amount: u256)An Approved event is emitted when allowance is modified through any method.
The following OP_20 methods emits this event in their provided implementations:
| Name | Type | Required | Description |
|---|---|---|---|
| owner | Address | - | Token owner. |
| spender | Address | - | Authorized spender. |
| amount | u256 | - | New total allowance (not delta). |
class OP20BurnedEvent extends NetEvent {
constructor(from: Address, amount: u256);
}constructor(from: Address, amount: u256)A Burned event is emitted when tokens are permanently removed from circulation, decreasing total number of tokens in circulation (totalSupply).
The following OP_20 methods emits this event in their provided implementations:
| Name | Type | Required | Description |
|---|---|---|---|
| from | Address | - | Address losing tokens. |
| amount | u256 | - | Number of tokens destroyed. |
class OP20MintedEvent extends NetEvent {
constructor(to: Address, amount: u256)
}constructor(to: Address, amount: u256)A Minted event is emitted when new tokens are created, increasing total number of in circulation (totalSupply).
The following OP_20 methods emits this event in their provided implementations:
| Name | Type | Required | Description |
|---|---|---|---|
| to | Address | - | Recipient of new tokens. |
| amount | u256 | - | Number of tokens created. |
class OP20TransferredEvent extends NetEvent {
constructor(operator: Address, from: Address, to: Address, amount: u256);
}constructor(operator: Address, from: Address, to: Address, amount: u256)A Transferred event is emitted on all successful transfers.
The following OP_20 methods emits this event in their provided implementations:
| Name | Type | Required | Description |
|---|---|---|---|
| operator | Address | - | Who initiated the transfer. |
| from | Address | - | Source of tokens. |
| to | Address | - | Destination of tokens. |
| amount | u256 | - | Number of tokens transferred. |
The IOP20Receiver interface is not implemented by the OP20 abstract class. Instead, derived classes must provide their own implementation.
interface IOP20Receiver {
onOP20Received(callData: Calldata): BytesWriter;
}
// Example
@final
export class ContractEx extends ReentrancyGuard implements IOP20Receiver {
...
public override execute(method: Selector, calldata: Calldata): BytesWriter {
let writer: BytesWriter;
switch (method) {
case encodeSelector('onOP20Received(address,address,uint256,bytes)'):
return this.onOP20Received(calldata);
default:
return super.execute(method, calldata);
}
return writer;
}
public onOP20Received(calldata: Calldata): BytesWriter {
const operator = calldata.readAddress();
const from = calldata.readAddress();
const amount = calldata.readU256();
const data: Uint8Array = calldata.readBytesWithLength();
// Custom logic here if needed
...
const writer = new BytesWriter(SELECTOR_BYTE_LENGTH);
writer.writeSelector(ON_OP_20_RECEIVED_SELECTOR);
return writer;
}
...
}export class OP20InitParameters {
readonly maxSupply: u256;
readonly decimals: u8;
readonly name: string;
readonly symbol: string;
readonly icon: string;
constructor(maxSupply: u256, decimals: u8, name: string, symbol: string, icon: string = '') {
this.maxSupply = maxSupply;
this.decimals = decimals;
this.name = name;
this.symbol = symbol;
this.icon = icon;
}
}constructorThe token metadata used to initialize the token when calling the instantiate() method during deployment.
| Name | Type | Required | Description |
|---|---|---|---|
| maxSupply | u256 | - | |
| decimals | u8 | - | Valid range: from 0 to 32. |
| name | string | - | |
| symbol | string | - | |
| icon | string | - | Any valid URL (http(s) or ipfs). Default to empty string when not specified. |
Type definitions only, not concrete implementations:
These type definitions define the data schema used by methods for signature validation and hash generation, such as signed allowance operations and the domainSeparator method.
Refer to the OP_20 Standard specification for detailed definitions.