Skip to main content

Contract Runtime

The Contract Runtime on OP_NET, powered by @btc-vision/btc-runtime/runtime, provides developers with tools to interact with the blockchain environment. This guide explains the key features of the Blockchain class and its associated components, enabling advanced contract functionality.


Blockchain Documentation

The Blockchain object is essential for executing smart contracts within the OP_NET runtime. It provides the necessary context, such as the transaction origin, sender, block details, and contract-specific information.


Public Properties

1. tx.origin

Property Details
  • Type: Address
  • Description: Represents the initial sender of the transaction. (equivalent to tx.origin in Solidity)
  • Usage Example:
    let txOrigin: Address = Blockchain.tx.origin;
    Blockchain.log(`Transaction Origin: ${txOrigin}`);

2. tx.sender

Property Details
  • Type: Address
  • Description: Refers to the immediate caller of the transaction. (equivalent to msg.sender in Solidity)
  • Usage Example:
    let txSender: Address = Blockchain.tx.sender;
    Blockchain.log(`Transaction Sender: ${txSender}`);

3. block.medianTimestamp

Property Details
  • Type: u64
  • Description: Timestamp of the block in which the transaction is executed.
  • Usage Example:
    let blockTimestamp: u64 = Blockchain.block.medianTimestamp;
    Blockchain.log(`Block Timestamp: ${blockTimestamp}`);

4. contract

Property Details
  • Type: OP_NET
  • Description: Accesses the current contract instance.
  • Usage Example:
    let currentContract: OP_NET = Blockchain.contract;

5. nextPointer

Property Details
  • Type: u16
  • Description: Manages dynamic storage pointers.
  • Usage Example:
    let pointer: u16 = Blockchain.nextPointer;
    Blockchain.log(`Next Pointer: ${pointer}`);

6. contractDeployer

Property Details
  • Type: Address
  • Description: The contract deployer's address.
  • Usage Example:
    let contractDeployer: Address = Blockchain.contractDeployer;
    Blockchain.log(`Contract Deployer: ${contractDeployer}`);

7. contractAddress

Property Details
  • Type: Address
  • Description: The deployed address of the contract.
  • Usage Example:
    let deployedAddress: Address = Blockchain.contractAddress;
    Blockchain.log(`Deployed Contract Address: ${deployedAddress}`);

8. block.number

Property Details
  • Type: u256
  • Description: The current block number as a 256-bit unsigned integer.
  • Usage Example:
    let currentBlockNum: u256 = Blockchain.block.number;
    Blockchain.log(`Current Block Number: ${currentBlockNum}`);

9. block.numberU64

Property Details
  • Type: u64
  • Description: The current block number as a 64-bit unsigned integer.
  • Usage Example:
    let currentBlockNum: u64 = Blockchain.block.numberU64;
    Blockchain.log(`Current Block Number: ${currentBlockNum}`);

Public Methods

1. call(destinationContract: Address, calldata: BytesWriter)

Method Details
  • Returns: BytesReader
  • Description: Executes a call to another contract.
  • Usage Example:
    let destination: Address = ...;
    let calldata = new BytesWriter(length);
    calldata.writeString('methodName');
    let response = Blockchain.call(destination, calldata);
    Blockchain.log(`Response: ${response}`);

2. log(data: string)

Method Details
  • Description: Logs string data for debugging or tracking. (only available in the development environment)
  • Usage Example:
    Blockchain.log("Execution started.");

3. deployContract(hash: u256, bytecode: Uint8Array)

Method Details
  • Returns: DeployContractResponse
  • Description: Deploys a contract using a hash and bytecode.
  • Usage Example:
    let contractHash = u256.fromU64(0x1234567890); // Your contract hash.
    let bytecode: Uint8Array = ...; // Your contract bytecode.
    let deployResponse = Blockchain.deployContract(contractHash, bytecode);
    Blockchain.log(`Deployed Address: ${deployResponse.contractAddress}`);

4. encodeVirtualAddress(virtualAddress: u8[])

Method Details
  • Returns: Address
  • Description: Encodes a virtual address into a standard format.
  • Usage Example:
    let virtualAddr: u8[] = ...;
    let encodedAddr: Address = Blockchain.encodeVirtualAddress(virtualAddr);
    Blockchain.log(`Encoded Address: ${encodedAddr}`);

Loading and Storing Pointers

1. Encoding and Hashing Process

Storage on OP_NET uses a combination of pointers (u16) and sub-pointers (u256) for efficient data management. These are encoded and hashed into a MemorySlotPointer.

Encoding Example

export function encodePointerHash(pointer: u16, sub: u256): MemorySlotPointer {
const buffer = new Uint8Array(34);
const mergedKey = [u8(pointer & 0xff), u8((pointer >> 8) & 0xff)];
buffer.set(mergedKey, 0);
buffer.set(sub.toUint8Array(), 2);

return bytes32(Sha256.hash(buffer));
}

2. Usage Example in a Contract

Let's consider a simple contract that stores and retrieves data using pointers.

Contract Implementation

class MyContract {
private pointer: u16;
private subPointer: MemorySlotPointer;

constructor(pointer: u16, subKey: string) {
this.pointer = pointer;
this.subPointer = encodePointer(
this.pointer,
Uint8Array.wrap(String.UTF8.encode(subKey))
);
}

public storeData(value: u256): void {
const storageKey = encodePointerHash(this.pointer, this.subPointer);
Blockchain.setStorageAt(storageKey, value);
}

public retrieveData(): u256 {
const storageKey = encodePointerHash(this.pointer, this.subPointer);
return Blockchain.getStorageAt(storageKey, u256.Zero);
}
}