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);
}
}