Sapphire Contracts Lib

NPM npm

A library for privacy focused smart contract development.

  • Implementations of OPL smart contracts
  • Sapphire library precompiles and cryptographic primitives
  • Wrapped Rose example

Overview

Installation

$ pnpm install @oasisprotocol/sapphire-contracts

Usage

Once installed, you can import and use the Sapphire contracts as follows:

pragma solidity ^0.8.13;

import "@oasisprotocol/sapphire-contracts/contracts/Sapphire.sol";

contract RandomNumber {
  function generateNumber() public view returns (uint) {
    return uint(bytes32(Sapphire.randomBytes(32, "")));
  }
}

Documentation

See the user's guide for Sapphire and OPL.

The generated API reference is hosted at api.docs.oasis.io.

Generating API docs locally requires Foundry and mdbook-pagetoc. To install them and generate the docs execute:

curl -L https://foundry.paradigm.xyz | bash
cargo install mdbook-pagetoc
pnpm doc

The API docs index will be located in sol/sapphire-contracts/book/index.html.

Contribute

There are many ways you can participate and help build high quality software. Check out the contribution guide!

Contents

A13e

Git Source

This is the interface for universal authentication mechanism (e.g. SIWE):

  1. The user-facing app calls login() to generate the bearer token on-chain.
  2. Any smart contract method that requires authentication accept this token as an argument. Then, it passes the token to authMsgSender() to verify it and obtain the authenticated user address. This address can then serve as a user ID for authorization.

State Variables

_revokedBearers

A mapping of revoked bearers. Access it directly or use the checkRevokedBearer modifier.

mapping(bytes32 => bool) internal _revokedBearers;

Functions

checkRevokedBearer

Reverts if the given bearer was revoked

modifier checkRevokedBearer(bytes calldata bearer);

login

Verify the login message and its signature and generate the bearer token.

function login(string calldata message, SignatureRSV calldata sig) external view virtual returns (bytes memory);

authMsgSender

Validate the bearer token and return authenticated msg.sender.

function authMsgSender(bytes calldata bearer) internal view virtual returns (address);

revokeBearer

Revoke the bearer token with the corresponding hash. e.g. In case when the bearer token is leaked or for extra-secure apps on every logout.

function revokeBearer(bytes32 bearer) internal;

Errors

RevokedBearer

The bearer token was revoked

error RevokedBearer();

Bearer

Git Source

struct Bearer {
    string domain;
    address userAddr;
    uint256 validUntil;
}

SiweAuth

Git Source

Inherits: A13e

Inherit this contract, if you wish to enable SIWE-based authentication for your contract methods that require authenticated calls. The smart contract needs to be bound to a domain (passed in constructor).

Example

contract MyContract is SiweAuth {
address private _owner;
modifier onlyOwner(bytes calldata bearer) {
if (authMsgSender(bearer) != _owner) {
revert("not allowed");
}
_;
}
constructor(string memory domain) SiweAuth(domain) {
_owner = msg.sender;
}
function getSecretMessage(bytes calldata bearer) external view onlyOwner(bearer) returns (string memory) {
return "Very secret message";
}
}

State Variables

_domain

Domain which the dApp is associated with

string private _domain;

_bearerEncKey

Encryption key which the bearer tokens are encrypted with

bytes32 private _bearerEncKey;

DEFAULT_VALIDITY

Default bearer token validity, if no expiration-time provided

uint256 private constant DEFAULT_VALIDITY = 24 hours;

Functions

constructor

Instantiate the contract which uses SIWE for authentication and runs on the specified domain.

constructor(string memory inDomain);

login

function login(string calldata siweMsg, SignatureRSV calldata sig) external view override returns (bytes memory);

domain

Return the domain associated with the dApp.

function domain() public view returns (string memory);

authMsgSender

function authMsgSender(bytes calldata bearer) internal view override checkRevokedBearer(bearer) returns (address);

Errors

ChainIdMismatch

Chain ID in the SIWE message does not match the actual chain ID

error ChainIdMismatch();

DomainMismatch

Domain in the SIWE message does not match the domain of a dApp

error DomainMismatch();

AddressMismatch

User address in the SIWE message does not match the message signer's address

error AddressMismatch();

NotBeforeInFuture

The Not before value in the SIWE message is still in the future

error NotBeforeInFuture();

Expired

The bearer token validity or the Expires value in the SIWE message is in the past

error Expired();

Contents

Enclave

Git Source

Inherits: Endpoint

The Sapphire-side of an OPL dApp.

Functions

constructor

constructor(address _host, bytes32 _hostChain) Endpoint(_host, _hostChain);

AutoConfigUnavailable

Git Source

Unable to automatically configure OPL. Please use the manual version of the base contract.

error AutoConfigUnavailable();

MissingRemoteAddr

Git Source

The remote endpoint's contract address was missing.

error MissingRemoteAddr();

MissingRemoteChainId

Git Source

The remote endpoint's chain ID was missing.

error MissingRemoteChainId();

SelfCallDisallowed

Git Source

Calls to contracts on the same chain are not allowed unless on a local testnet.

error SelfCallDisallowed();

UnknownEndpoint

Git Source

The requested endpoint does not exist.

error UnknownEndpoint();

Result

Git Source

The outcome of the message call.

enum Result {
    PermanentFailure,
    TransientFailure,
    Success
}

ICelerMessageBus

Git Source

Functions

feeBase

function feeBase() external view returns (uint256);

feePerByte

function feePerByte() external view returns (uint256);

sendMessage

function sendMessage(address _host, uint256 _hostChainId, bytes calldata _message) external payable;

BaseEndpoint

Git Source

State Variables

messageBus

address internal immutable messageBus;

inOrder

bool private immutable inOrder;

remote

address private remote;

remoteChainId

uint256 private remoteChainId;

endpoints

mapping(bytes32 => function(bytes calldata) returns (Result)) private endpoints;

txSeq

uint256 private txSeq;

rxSeq

uint256 private rxSeq;

Functions

constructor

constructor(address _remote, uint256 _remoteChainId, address _messageBus, bool _inOrder);

registerEndpoint

function registerEndpoint(bytes memory _method, function(bytes calldata) returns (Result) _cb) internal;

postMessage

function postMessage(bytes memory _method) internal returns (uint256);

postMessage

Calls the remote endpoint, returning the amount of native token charged for the operation.

function postMessage(bytes memory _method, bytes memory _message) internal returns (uint256);

executeMessage

Celer message bus callback function.

function executeMessage(address _sender, uint64 _senderChainId, bytes calldata _message, address)
    external
    payable
    returns (uint256);

estimateFee

function estimateFee(uint256 _msgLen) internal view returns (uint256);

_isLocalNetwork

function _isLocalNetwork() internal view returns (bool);

Endpoint

Git Source

Inherits: BaseEndpoint

An app that sends or receives using OPL.

Functions

constructor

constructor(address _remote, bytes32 _remoteChainName)
    BaseEndpoint(_remote, _getRemoteChainId(_remoteChainName), _getBus(_remote, _remoteChainName), false);

_getRemoteChainId

Git Source

function _getRemoteChainId(bytes32 _remoteChainName) view returns (uint256);

_getChainConfig

Git Source

Configs from https://im-docs.celer.network/developer/contract-addresses-and-rpc-info.

function _getChainConfig(uint256 _chainId) pure returns (address _messageBus, bool _isTestnet);

autoswitch

Git Source

Autoswitch automatically picks the remote network based on the network the contract on which the contract has already been deployed. When on testnet, the remote chain will be the testnet version of the provided chain. When running locally, the remote chain will be this one and the contracts will call each other without going through a message bus. This is helpful for debugging logic but does not test gas fee payment and other moving parts.

function autoswitch(bytes32 protocol) view returns (bytes32 networkName);

_getBus

Git Source

function _getBus(address _remote, bytes32 _remoteChainName) view returns (address);

_chainName2ChainId

Git Source

function _chainName2ChainId(bytes32 name) pure returns (uint256);

Host

Git Source

Inherits: Endpoint

The L1-side of an OPL dApp.

Functions

constructor

constructor(address _enclave) Endpoint(_enclave, autoswitch("sapphire"));

Contents

Contents

SiweAuthTests

Git Source

Inherits: SiweAuth

State Variables

_owner

address private _owner;

Functions

constructor

constructor(string memory domain) SiweAuth(domain);

testVerySecretMessage

function testVerySecretMessage(bytes calldata bearer) external view returns (string memory);

testLogin

function testLogin(string calldata message, SignatureRSV calldata sig) external view returns (bytes memory);

testAuthMsgSender

function testAuthMsgSender(bytes calldata bearer) external view returns (address);

testRevokeBearer

function testRevokeBearer(bytes32 bearer) external;

doNothing

function doNothing() external;

CBOR_InvalidKey

Git Source

While parsing CBOR map, unexpected key

error CBOR_InvalidKey();

CBOR_InvalidMap

Git Source

While parsing CBOR map, length is invalid, or other parse error

error CBOR_InvalidMap();

CBOR_InvalidLength

Git Source

While parsing CBOR structure, data length was unexpected

error CBOR_InvalidLength(uint256);

CBOR_InvalidUintPrefix

Git Source

Value cannot be parsed as a uint

error CBOR_InvalidUintPrefix(uint8);

CBOR_InvalidUintSize

Git Source

CBOR spec supports, 1, 2, 4 & 8 byte uints. Caused by parse error.

error CBOR_InvalidUintSize(uint8);

CBOR_Error_ValueOutOfRange

Git Source

CBOR parsed value is out of expected range

error CBOR_Error_ValueOutOfRange(uint256 value, uint256 maxValue);

CBOR_Error_BufferOverrun

Git Source

Buffer too short to parse expected value

error CBOR_Error_BufferOverrun(uint256 len, uint256 offset, uint256 need);

CBOR_Error_BytesTooLong

Git Source

Byte array is too long

Solidity has 256bit length prefixes for byte arrays. We decided for a reasonable cutoff point (64kb), so at most a 2-byte uint describing the array length.

error CBOR_Error_BytesTooLong(uint256 byteLength);

parseUint

Git Source

function parseUint(bytes memory result, uint256 offset) pure returns (uint256 newOffset, uint256 value);

encodeBytes

Git Source

function encodeBytes(bytes memory in_bytes) pure returns (bytes memory out_cbor);

parseUint128

Git Source

function parseUint128(bytes memory result, uint256 offset) pure returns (uint256 newOffset, uint128 value);

parseMapStart

Git Source

function parseMapStart(bytes memory in_data, uint256 in_offset) pure returns (uint256 n_entries, uint256 out_offset);

parseUint64

Git Source

function parseUint64(bytes memory result, uint256 offset) pure returns (uint256 newOffset, uint64 value);

parseKey

Git Source

function parseKey(bytes memory result, uint256 offset) pure returns (uint256 newOffset, bytes32 keyDigest);

encodeUint

Git Source

we don't follow bignum tagged encoding See: https://www.rfc-editor.org/rfc/rfc8949.html#section-3.4.3

function encodeUint(uint256 value) pure returns (bytes memory);

_deriveKey

Git Source

function _deriveKey(bytes32 in_peerPublicKey, Sapphire.Curve25519SecretKey in_x25519_secret) view returns (bytes32);

_encryptInner

Git Source

function _encryptInner(
    bytes memory in_data,
    Sapphire.Curve25519SecretKey in_x25519_secret,
    bytes15 nonce,
    bytes32 peerPublicKey
) view returns (bytes memory out_encrypted);

function encryptCallData

Git Source

encryptCallData(bytes)

function encryptCallData(bytes memory in_data) view returns (bytes memory out_encrypted);

encryptCallData(bytes, Sapphire.Curve25519PublicKey, Sapphire.Curve25519SecretKey, bytes15, uint256, bytes32)

function encryptCallData(
    bytes memory in_data,
    Sapphire.Curve25519PublicKey myPublic,
    Sapphire.Curve25519SecretKey mySecret,
    bytes15 nonce,
    uint256 epoch,
    bytes32 peerPublicKey
) view returns (bytes memory out_encrypted);

StakingAddress

Git Source

21 byte version-prefixed address (1 byte version, 20 bytes truncated digest).

type StakingAddress is bytes21;

StakingSecretKey

Git Source

32 byte secret key.

type StakingSecretKey is bytes32;

ConsensusUtils

Git Source

Generate Oasis wallets for use with staking at the consensus level.

State Variables

ADDRESS_V0_CONTEXT_IDENTIFIER

The unique context for v0 staking account addresses.

Note: see: @oasisprotocol/oasis-core :: go/staking/api/address.go

string private constant ADDRESS_V0_CONTEXT_IDENTIFIER = "oasis-core/address: staking";

ADDRESS_V0_CONTEXT_VERSION

uint8 private constant ADDRESS_V0_CONTEXT_VERSION = 0;

Functions

generateStakingAddress

Generate a random Ed25519 wallet for Oasis consensus-layer staking.

function generateStakingAddress(bytes memory personalization)
    internal
    view
    returns (StakingAddress publicAddress, StakingSecretKey secretKey);

Parameters

NameTypeDescription
personalizationbytesOptional user-specified entropy.

Returns

NameTypeDescription
publicAddressStakingAddressPublic address of the keypair.
secretKeyStakingSecretKeySecret key for the keypair.

_stakingAddressFromPublicKey

Derive the staking address from the public key.

function _stakingAddressFromPublicKey(bytes32 ed25519publicKey) internal view returns (bytes21);

Parameters

NameTypeDescription
ed25519publicKeybytes32Ed25519 public key.

_addressFromData

Derive an Oasis-style address.

function _addressFromData(string memory contextIdentifier, uint8 contextVersion, bytes memory data)
    internal
    view
    returns (bytes21);

Parameters

NameTypeDescription
contextIdentifierstringDomain separator.
contextVersionuint8Domain version.
databytesPublic point of the keypair.

DateTime

Git Source

Considers leap year, but not leap second.

Note: attribution: https://github.com/pipermerriam/ethereum-datetime/blob/master/contracts/contracts/DateTime.sol

State Variables

ORIGIN_YEAR

uint16 private constant ORIGIN_YEAR = 1970;

Functions

isLeapYear

function isLeapYear(uint16 year) internal pure returns (bool);

toTimestamp

Convert year, month, day, hour, minute, second to Unix timestamp.

Leap second is not supported.

function toTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute, uint8 second)
    internal
    pure
    returns (uint256 timestamp);

EIP1559Signer

Git Source

Functions

encodeUnsignedTx

Encode an unsigned EIP-1559 transaction for signing

function encodeUnsignedTx(EIP1559Tx memory rawTx) internal pure returns (bytes memory);

Parameters

NameTypeDescription
rawTxEIP1559TxTransaction to encode

encodeSignedTx

Encode a signed EIP-1559 transaction

function encodeSignedTx(EIP1559Tx memory rawTx, SignatureRSV memory rsv) internal pure returns (bytes memory);

Parameters

NameTypeDescription
rawTxEIP1559TxTransaction which was signed
rsvSignatureRSVR, S & V parameters of signature

signRawTx

Sign a raw transaction

function signRawTx(EIP1559Tx memory rawTx, address pubkeyAddr, bytes32 secretKey)
    internal
    view
    returns (SignatureRSV memory ret);

Parameters

NameTypeDescription
rawTxEIP1559TxTransaction to sign
pubkeyAddraddressEthereum address of secret key
secretKeybytes32Secret key used to sign

sign

Sign a transaction, returning it in EIP-1559 encoded form

function sign(address publicAddress, bytes32 secretKey, EIP1559Tx memory transaction)
    internal
    view
    returns (bytes memory);

Parameters

NameTypeDescription
publicAddressaddressEthereum address of secret key
secretKeybytes32Secret key used to sign
transactionEIP1559TxTransaction to sign

Structs

EIP1559Tx

struct EIP1559Tx {
    uint64 nonce;
    uint256 maxPriorityFeePerGas;
    uint256 maxFeePerGas;
    uint64 gasLimit;
    address to;
    uint256 value;
    bytes data;
    EIPTypes.AccessList accessList;
    uint256 chainId;
}

EIP155Signer

Git Source

Functions

encodeSignedTx

Encode a signed EIP-155 transaction.

function encodeSignedTx(EthTx memory rawTx, SignatureRSV memory rsv) internal pure returns (bytes memory);

Parameters

NameTypeDescription
rawTxEthTxTransaction which was signed.
rsvSignatureRSVR, S & V parameters of signature.

signRawTx

Sign a raw transaction, which will then need to be encoded to include the signature.

function signRawTx(EthTx memory rawTx, address pubkeyAddr, bytes32 secretKey)
    internal
    view
    returns (SignatureRSV memory ret);

Parameters

NameTypeDescription
rawTxEthTxTransaction to sign.
pubkeyAddraddressEthereum address of secret key.
secretKeybytes32Secret key used to sign.

sign

Sign a transaction, returning it in EIP-155 encoded form.

function sign(address publicAddress, bytes32 secretKey, EthTx memory transaction)
    internal
    view
    returns (bytes memory);

Parameters

NameTypeDescription
publicAddressaddressEthereum address of secret key.
secretKeybytes32Secret key used to sign.
transactionEthTxTransaction to sign.

Structs

EthTx

struct EthTx {
    uint64 nonce;
    uint256 gasPrice;
    uint64 gasLimit;
    address to;
    uint256 value;
    bytes data;
    uint256 chainId;
}

EIP2930Signer

Git Source

Functions

encodeUnsignedTx

Encode an unsigned EIP-2930 transaction for signing

function encodeUnsignedTx(EIP2930Tx memory rawTx) internal pure returns (bytes memory);

Parameters

NameTypeDescription
rawTxEIP2930TxTransaction to encode

encodeSignedTx

Encode a signed EIP-2930 transaction

function encodeSignedTx(EIP2930Tx memory rawTx, SignatureRSV memory rsv) internal pure returns (bytes memory);

Parameters

NameTypeDescription
rawTxEIP2930TxTransaction which was signed
rsvSignatureRSVR, S & V parameters of signature

signRawTx

Sign a raw transaction

function signRawTx(EIP2930Tx memory rawTx, address pubkeyAddr, bytes32 secretKey)
    internal
    view
    returns (SignatureRSV memory ret);

Parameters

NameTypeDescription
rawTxEIP2930TxTransaction to sign
pubkeyAddraddressEthereum address of secret key
secretKeybytes32Secret key used to sign

sign

Sign a transaction, returning it in EIP-2930 encoded form

function sign(address publicAddress, bytes32 secretKey, EIP2930Tx memory transaction)
    internal
    view
    returns (bytes memory);

Parameters

NameTypeDescription
publicAddressaddressEthereum address of secret key
secretKeybytes32Secret key used to sign
transactionEIP2930TxTransaction to sign

Structs

EIP2930Tx

struct EIP2930Tx {
    uint64 nonce;
    uint256 gasPrice;
    uint64 gasLimit;
    address to;
    uint256 value;
    bytes data;
    EIPTypes.AccessList accessList;
    uint256 chainId;
}

EIPTypes

Git Source

Functions

encodeAccessList

Encode an access list for EIP-1559 and EIP-2930 transactions

function encodeAccessList(AccessList memory list) internal pure returns (bytes memory);

Structs

AccessList

struct AccessList {
    AccessListItem[] items;
}

AccessListItem

struct AccessListItem {
    address addr;
    bytes32[] storageKeys;
}

SignatureRSV

Git Source

struct SignatureRSV {
    bytes32 r;
    bytes32 s;
    uint256 v;
}

EthereumUtils

Git Source

State Variables

K256_P

uint256 internal constant K256_P = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f;

K256_P_PLUS_1_OVER_4

uint256 internal constant K256_P_PLUS_1_OVER_4 = 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff0c;

PRECOMPILE_BIGMODEXP

address internal constant PRECOMPILE_BIGMODEXP = address(0x5);

Functions

expmod

function expmod(uint256 base, uint256 exponent, uint256 modulus) internal view returns (uint256 out);

k256DeriveY

Recover Y coordinate from X coordinate and sign bit.

function k256DeriveY(uint8 prefix, uint256 x) internal view returns (uint256 y);

Parameters

NameTypeDescription
prefixuint80x02 or 0x03 indicates sign bit of compressed point.
xuint256X coordinate.

k256Decompress

Decompress SEC P256 k1 point.

function k256Decompress(bytes memory pk) internal view returns (uint256 x, uint256 y);

Parameters

NameTypeDescription
pkbytes33 byte compressed public key.

Returns

NameTypeDescription
xuint256X coordinate.
yuint256Y coordinate.

k256PubkeyToEthereumAddress

function k256PubkeyToEthereumAddress(bytes memory pubkey) internal view returns (address);

toEthereumAddress

Convert SEC P256 k1 curve point to Ethereum address.

Note: see: https://gavwood.com/paper.pdf (pp. 212)

function toEthereumAddress(uint256 x, uint256 y) internal pure returns (address);

Parameters

NameTypeDescription
xuint256X coordinate.
yuint256Y coordinate.

splitDERSignature

Extracts the r and s parameters from a DER encoded ECDSA signature. The signature is an ASN1 encoded SEQUENCE of the variable length r and s INTEGERs.

| 0x30 | len(z) | 0x02 | len(r) |  r   | 0x02 | len(s) |  s   | = hex value
|  1   |   1    |   1  |   1    | 1-33 |  1   |   1    | 1-33 | = byte length

If the highest bit of either r or s is set, it will be prefix padded with a zero byte. There is exponentially decreasing probability that either r or s will be below 32 bytes. There is a very high probability that either r or s will be 33 bytes. This function only works if either r or s are 256bits or lower.

Note: see: https://bitcoin.stackexchange.com/questions/58853/how-do-you-figure-out-the-r-and-s-out-of-a-signature-using-python

function splitDERSignature(bytes memory der) internal pure returns (SignatureRSV memory rsv);

Parameters

NameTypeDescription
derbytesDER encoded ECDSA signature

Returns

NameTypeDescription
rsvSignatureRSVECDSA R point X coordinate, and S scalar

recoverV

function recoverV(address pubkeyAddr, bytes32 digest, SignatureRSV memory rsv) internal pure;

toEthereumSignature

Convert a Secp256k1PrehashedKeccak256 signature to one accepted by ecrecover.

Note: see: https://gavwood.com/paper.pdf (pp. 206)

function toEthereumSignature(bytes memory pubkey, bytes32 digest, bytes memory signature)
    internal
    view
    returns (address pubkeyAddr, SignatureRSV memory rsv);

Parameters

NameTypeDescription
pubkeybytes33 byte compressed public key.
digestbytes3232 byte pre-hashed message digest.
signaturebytesASN.1 DER encoded signature, as returned from Sapphire.sign.

Returns

NameTypeDescription
pubkeyAddraddress20 byte Ethereum address.
rsvSignatureRSVEthereum EcDSA RSV signature values.

sign

function sign(address pubkeyAddr, bytes32 secretKey, bytes32 digest) internal view returns (SignatureRSV memory rsv);

generateKeypair

Generate an Ethereum compatible SEC P256 k1 keypair and corresponding public address.

function generateKeypair() internal view returns (address pubkeyAddr, bytes32 secretKey);

Returns

NameTypeDescription
pubkeyAddraddressEthereum address.
secretKeybytes32Secret key used for signing.

Errors

expmod_Error

error expmod_Error();

k256DeriveY_Invalid_Prefix_Error

error k256DeriveY_Invalid_Prefix_Error();

k256Decompress_Invalid_Length_Error

error k256Decompress_Invalid_Length_Error();

DER_Split_Error

error DER_Split_Error();

recoverV_Error

error recoverV_Error();

RLPWriter

Git Source

Author: RLPWriter is a library for encoding Solidity types to RLP bytes. Adapted from Bakaoh's RLPEncode library (https://github.com/bakaoh/solidity-rlp-encode) with minor modifications to improve legibility.

Notes:

  • attribution: https://github.com/bakaoh/solidity-rlp-encode

  • attribution: https://raw.githubusercontent.com/Maia-DAO/solidity-rlp-encoder/main/rlp/RLPWriter.sol

Functions

writeBytes

RLP encodes a byte string.

function writeBytes(bytes memory _in) internal pure returns (bytes memory);

Parameters

NameTypeDescription
_inbytesThe byte string to encode.

Returns

NameTypeDescription
<none>bytesThe RLP encoded string in bytes.

writeList

RLP encodes a list of RLP encoded byte byte strings.

function writeList(bytes memory _in) internal pure returns (bytes memory);

Parameters

NameTypeDescription
_inbytesThe RLP encoded byte strings.

Returns

NameTypeDescription
<none>bytesThe RLP encoded list of items in bytes.

writeList

RLP encodes a list of RLP encoded byte byte strings.

function writeList(bytes[] memory _in) internal pure returns (bytes memory);

Parameters

NameTypeDescription
_inbytes[]The list of RLP encoded byte strings.

Returns

NameTypeDescription
<none>bytesThe RLP encoded list of items in bytes.

writeString

RLP encodes a string.

function writeString(string memory _in) internal pure returns (bytes memory);

Parameters

NameTypeDescription
_instringThe string to encode.

Returns

NameTypeDescription
<none>bytesThe RLP encoded string in bytes.

writeAddress

RLP encodes an address.

function writeAddress(address _in) internal pure returns (bytes memory);

Parameters

NameTypeDescription
_inaddressThe address to encode.

Returns

NameTypeDescription
<none>bytesThe RLP encoded address in bytes.

writeUint

RLP encodes a uint.

function writeUint(uint256 _in) internal pure returns (bytes memory);

Parameters

NameTypeDescription
_inuint256The uint256 to encode.

Returns

NameTypeDescription
<none>bytesThe RLP encoded uint256 in bytes.

writeBool

RLP encodes a bool.

function writeBool(bool _in) internal pure returns (bytes memory);

Parameters

NameTypeDescription
_inboolThe bool to encode.

Returns

NameTypeDescription
<none>bytesThe RLP encoded bool in bytes.

_writeLength

Encode the first byte and then the len in binary form if length is more than 55.

function _writeLength(uint256 _len, uint256 _offset) private pure returns (bytes memory);

Parameters

NameTypeDescription
_lenuint256The length of the string or the payload.
_offsetuint256128 if item is string, 192 if item is list.

Returns

NameTypeDescription
<none>bytesRLP encoded bytes.

_toBinary

Encode integer in big endian binary form with no leading zeroes.

function _toBinary(uint256 _x) private pure returns (bytes memory);

Parameters

NameTypeDescription
_xuint256The integer to encode.

Returns

NameTypeDescription
<none>bytesRLP encoded bytes.

_memcpy

Copies a piece of memory to another location.

Note: attribution: https://github.com/Arachnid/solidity-stringutils

function _memcpy(uint256 _dest, uint256 _src, uint256 _len) private pure;

Parameters

NameTypeDescription
_destuint256Destination location.
_srcuint256Source location.
_lenuint256Length of memory to copy.

_flatten

Flattens a list of byte strings into one byte string.

Note: attribution: https://github.com/sammayo/solidity-rlp-encoder

function _flatten(bytes[] memory _list) private pure returns (bytes memory);

Parameters

NameTypeDescription
_listbytes[]List of byte strings to flatten.

Returns

NameTypeDescription
<none>bytesThe flattened byte string.

Sapphire

Git Source

This library provides a number of convenient wrappers for cryptographic operations such as the x25519 key derivation, Deoxys-II-based encryption and decryption, signing key generation, message digest signing and verification, gas padding and hashing. Most of the mentioned functions are implemented as Sapphire's precompiles and are cheap to call.

Calling Precompiles Manually

You can override the wrappers and call Sapphire precompiles by dispatching calls to specific well-known contract addresses, as described below. The Precompile address section of each function will show you the address of the corresponding precompile. Input parameters should be packed into a contiguous memory region with each chunk of data padded to 32 bytes as usual. The recommended way to construct parameter byte sequences in Solidity is with abi.encode and abi.decode, which will transparently handle things like putting bytes lengths in the correct position.

State Variables

RANDOM_BYTES

address internal constant RANDOM_BYTES = 0x0100000000000000000000000000000000000001;

DERIVE_KEY

address internal constant DERIVE_KEY = 0x0100000000000000000000000000000000000002;

ENCRYPT

address internal constant ENCRYPT = 0x0100000000000000000000000000000000000003;

DECRYPT

address internal constant DECRYPT = 0x0100000000000000000000000000000000000004;

GENERATE_SIGNING_KEYPAIR

address internal constant GENERATE_SIGNING_KEYPAIR = 0x0100000000000000000000000000000000000005;

SIGN_DIGEST

address internal constant SIGN_DIGEST = 0x0100000000000000000000000000000000000006;

VERIFY_DIGEST

address internal constant VERIFY_DIGEST = 0x0100000000000000000000000000000000000007;

CURVE25519_PUBLIC_KEY

address internal constant CURVE25519_PUBLIC_KEY = 0x0100000000000000000000000000000000000008;

GAS_USED

address internal constant GAS_USED = 0x0100000000000000000000000000000000000009;

PAD_GAS

address internal constant PAD_GAS = 0x010000000000000000000000000000000000000a;

SHA512_256

address internal constant SHA512_256 = 0x0100000000000000000000000000000000000101;

SHA512

address internal constant SHA512 = 0x0100000000000000000000000000000000000102;

SHA384

address internal constant SHA384 = 0x0100000000000000000000000000000000000104;

Functions

randomBytes

Generate num_bytes pseudo-random bytes, with an optional personalization string (pers) added into the hashing algorithm to increase domain separation when needed.

Precompile address

0x0100000000000000000000000000000000000001

Gas cost

10,000 minimum plus 240 per output word plus 60 per word of the personalization string.

Implementation details

The mode (e.g. simulation or "view call" vs transaction execution) is fed to TupleHash (among other block-dependent components) to derive the "key id", which is then used to derive a per-block VRF key from epoch-ephemeral entropy (using KMAC256 and cSHAKE) so a different key id will result in a unique per-block VRF key. This per-block VRF key is then used to create the per-block root RNG which is then used to derive domain-separated (using Merlin transcripts) per-transaction random RNGs which are then exposed via this precompile. The KMAC, cSHAKE and TupleHash algorithms are SHA-3 derived functions defined in NIST Special Publication 800-185.

DANGER: Prior to Sapphire ParaTime 0.6.0

All view queries and simulated transactions (via eth_call) would receive the same entropy in-between blocks if they use the same num_bytes and pers parameters. If your contract requires confidentiality you should generate a secret in the constructor to be used with view calls:

Sapphire.randomBytes(64, abi.encodePacked(msg.sender, this.perContactSecret));

Example

bytes memory randomPad = Sapphire.randomBytes(64, "");
function randomBytes(uint256 numBytes, bytes memory pers) internal view returns (bytes memory);

Parameters

NameTypeDescription
numBytesuint256The number of bytes to return.
persbytesAn optional personalization string to increase domain separation.

Returns

NameTypeDescription
<none>bytesThe random bytes. If the number of bytes requested is too large (over 1024), a smaller amount (1024) will be returned.

generateCurve25519KeyPair

Generates a Curve25519 keypair.

function generateCurve25519KeyPair(bytes memory pers)
    internal
    view
    returns (Curve25519PublicKey pk, Curve25519SecretKey sk);

Parameters

NameTypeDescription
persbytesAn optional personalization string used to add domain separation.

Returns

NameTypeDescription
pkCurve25519PublicKeyThe Curve25519 public key. Useful for key exchange.
skCurve25519SecretKeyThe Curve25519 secret key. Pairs well with deriveSymmetricKey.

deriveSymmetricKey

Derive a symmetric key from a pair of keys using x25519.

Precompile address

0x0100000000000000000000000000000000000002

Gas cost

100,000

Example

bytes32 publicKey = ... ;
bytes32 privateKey = ... ;
bytes32 symmetric = Sapphire.deriveSymmetricKey(publicKey, privateKey);
function deriveSymmetricKey(Curve25519PublicKey peerPublicKey, Curve25519SecretKey secretKey)
    internal
    view
    returns (bytes32);

Parameters

NameTypeDescription
peerPublicKeyCurve25519PublicKeyThe peer's public key.
secretKeyCurve25519SecretKeyYour secret key.

Returns

NameTypeDescription
<none>bytes32A derived symmetric key.

encrypt

Encrypt and authenticate the plaintext and additional data using DeoxysII.

Precompile address

0x0100000000000000000000000000000000000003

Gas cost

50,000 minimum plus 100 per word of input

Example

bytes32 key = ... ;
bytes32 nonce = ... ;
bytes memory text = "plain text";
bytes memory ad = "additional data";
bytes memory encrypted = Sapphire.encrypt(key, nonce, text, ad);
bytes memory decrypted = Sapphire.decrypt(key, nonce, encrypted, ad);
function encrypt(bytes32 key, bytes32 nonce, bytes memory plaintext, bytes memory additionalData)
    internal
    view
    returns (bytes memory);

Parameters

NameTypeDescription
keybytes32The key to use for encryption.
noncebytes32The nonce. Note that only the first 15 bytes of this parameter are used.
plaintextbytesThe plaintext to encrypt and authenticate.
additionalDatabytesThe additional data to authenticate.

Returns

NameTypeDescription
<none>bytesThe ciphertext with appended auth tag.

decrypt

Decrypt and authenticate the ciphertext and additional data using DeoxysII. Reverts if the auth tag is incorrect.

Precompile address

0x0100000000000000000000000000000000000004

Gas cost

50,000 minimum plus 100 per word of input

Example

bytes32 key = ... ;
bytes32 nonce = ... ;
bytes memory text = "plain text";
bytes memory ad = "additional data";
bytes memory encrypted = Sapphire.encrypt(key, nonce, text, ad);
bytes memory decrypted = Sapphire.decrypt(key, nonce, encrypted, ad);
function decrypt(bytes32 key, bytes32 nonce, bytes memory ciphertext, bytes memory additionalData)
    internal
    view
    returns (bytes memory);

Parameters

NameTypeDescription
keybytes32The key to use for decryption.
noncebytes32The nonce. Note that only the first 15 bytes of this parameter are used.
ciphertextbytesThe ciphertext with tag to decrypt and authenticate.
additionalDatabytesThe additional data to authenticate against the ciphertext.

Returns

NameTypeDescription
<none>bytesThe original plaintext.

generateSigningKeyPair

Generate a public/private key pair using the specified method and seed. The available methods are items in the Sapphire.SigningAlg enum. Note, however, that the generation method ignores subvariants, so all three Ed25519-based are equivalent, and all Secp256k1 & Secp256r1 based methods are equivalent. Sr25519 is not available and will return an error.

Precompile address

0x0100000000000000000000000000000000000005

Gas Cost

Ed25519: 1,000 gas
  • 0 (Ed25519Oasis)
  • 1 (Ed25519Pure)
  • 2 (Ed25519PrehashedSha512)
Secp256k1: 1,500 gas.
  • 3 (Secp256k1Oasis)
  • 4 (Secp256k1PrehashedKeccak256)
  • 5 (Secp256k1PrehashedSha256)
Secp256r1: 4,000 gas
  • 7 (Secp256r1PrehashedSha256)
Secp384r1: 18,000 gas
  • 8 (Secp384r1PrehashedSha384)

Key Formats

Ed25519

Public key: 32 bytes Secret key: 32 bytes

Secp256k1 & Secp256r1

Public key: 33 bytes, compressed format (0x02 or 0x03 prefix, then 32 byte X coordinate). Secret key: 32 bytes

Secp384r1

Public key: 49 bytes, compressed format (0x02 or 0x03 prefix, then 48 byte X coordinate). Secret key: 48 bytes

Example

bytes memory seed = hex"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
bytes memory publicKey;
bytes memory privateKey;
(publicKey, privateKey) = Sapphire.generateSigningKeyPair(Sapphire.SigningAlg.Ed25519Pure, seed);
function generateSigningKeyPair(SigningAlg alg, bytes memory seed)
    internal
    view
    returns (bytes memory publicKey, bytes memory secretKey);

Parameters

NameTypeDescription
algSigningAlgThe signing alg for which to generate a keypair.
seedbytesThe seed to use for generating the key pair. You can use the randomBytes method if you don't already have a seed.

Returns

NameTypeDescription
publicKeybytesThe public part of the keypair.
secretKeybytesThe secret part of the keypair.

sign

Sign a message within the provided context using the specified algorithm, and return the signature. The context_or_digest and messages parameters change in meaning slightly depending on the method requested. For methods that take a context in addition to the message you must pass the context in the context_or_digest parameter and use message as expected. For methods that take a pre-existing hash of the message, pass that in context_or_digest and leave message empty. Specifically the Ed25519Oasis and Secp256k1Oasis variants take both a context and a message (each are variable length bytes), the context serves as a domain separator.

Precompile address

0x0100000000000000000000000000000000000006

Gas cost

See below for the method-dependent base cost, plus 8 gas per 32 bytes of context and message except digest.

Signing algorithms

  • 0 (Ed25519Oasis): 1,500 gas, variable length context and message.
  • 1 (Ed25519Pure): 1,500 gas, empty context, variable length message.
  • 2 (Ed25519PrehashedSha512): 1,500 gas, pre-existing SHA-512 hash (64 bytes) as context, empty message.
  • 3 (Secp256k1Oasis): 3,000 gas, variable length context and message
  • 4 (Secp256k1PrehashedKeccak256): 3,000 gas, pre-existing hash (32 bytes) as context, empty message.
  • 5 (Secp256k1PrehashedSha256): 3,000 gas, pre-existing hash (32 bytes) as context, empty message.
  • 7 (Secp256r1PrehashedSha256): 9,000 gas, pre-existing hash (32 bytes) as context, empty message.
  • 8 (Secp384r1PrehashedSha384): 43,200 gas, pre-existing hash (32 bytes) as context, empty message.

Example

Sapphire.SigningAlg alg = Sapphire.SigningAlg.Ed25519Pure;
bytes memory pk;
bytes memory sk;
(pk, sk) = Sapphire.generateSigningKeyPair(alg, Sapphire.randomBytes(32, ""));
bytes memory signature = Sapphire.sign(alg, sk, "", "signed message");

Note: see: @oasisprotocol/oasis-sdk :: precompile/confidential.rs :: call_sign

function sign(SigningAlg alg, bytes memory secretKey, bytes memory contextOrHash, bytes memory message)
    internal
    view
    returns (bytes memory signature);

Parameters

NameTypeDescription
algSigningAlgThe signing algorithm to use.
secretKeybytesThe secret key to use for signing. The key must be valid for use with the requested algorithm.
contextOrHashbytesDomain-Separator Context, or precomputed hash bytes.
messagebytesMessage to sign, should be zero-length if precomputed hash given.

Returns

NameTypeDescription
signaturebytesThe resulting signature.

verify

Verifies that the provided digest was signed with using the secret key corresponding to the provided private key and the specified signing algorithm. The method, context_or_digest and message parameters have the same meaning as described above in the sign() function.

Precompile address

0x0100000000000000000000000000000000000007

Gas cost

The algorithm-specific base cost below, with an additional 8 gas per 32 bytes of context and message for the Ed25519Oasis, Ed25519Pure and Secp256k1Oasis algorithms.

  • 0 (Ed25519Oasis): 2,000 gas
  • 1 (Ed25519Pure): 2,000 gas
  • 2 (Ed25519PrehashedSha512): 2,000 gas
  • 3 (Secp256k1Oasis): 3,000 gas
  • 4 (Secp256k1PrehashedKeccak256): 3,000 gas
  • 5 (Secp256k1PrehashedSha256): 3,000 gas
  • 7 (Secp256r1PrehashedSha256): 7,900 gas
  • 8 (Secp384r1PrehashedSha384): 37,920 gas

Example

Sapphire.SigningAlg alg = Sapphire.SigningAlg.Secp256k1PrehashedKeccak256;
bytes memory pk;
bytes memory sk;
bytes memory digest = abi.encodePacked(keccak256("signed message"));
(pk, sk) = Sapphire.generateSigningKeyPair(alg, Sapphire.randomBytes(32, ""));
bytes memory signature = Sapphire.sign(alg, sk, digest, "");
require( Sapphire.verify(alg, pk, digest, "", signature) );

Note: see: @oasisprotocol/oasis-sdk :: precompile/confidential.rs :: call_verify

function verify(
    SigningAlg alg,
    bytes memory publicKey,
    bytes memory contextOrHash,
    bytes memory message,
    bytes memory signature
) internal view returns (bool verified);

Parameters

NameTypeDescription
algSigningAlgThe signing algorithm by which the signature was generated.
publicKeybytesThe public key against which to check the signature.
contextOrHashbytesDomain-Separator Context, or precomputed hash bytes
messagebytesThe hash of the message that was signed, should be zero-length if precomputed hash was given.
signaturebytesThe signature to check.

Returns

NameTypeDescription
verifiedboolWhether the signature is valid for the given parameters.

padGas

Set the current transactions gas usage to a specific amount

Will cause a reversion if the current usage is more than the amount.

Note: see: @oasisprotocol/oasis-sdk :: precompile/gas.rs :: call_pad_gas

function padGas(uint128 toAmount) internal view;

Parameters

NameTypeDescription
toAmountuint128Gas usage will be set to this amount

gasUsed

Returns the amount of gas currently used by the transaction

Note: see: @oasisprotocol/oasis-sdk :: precompile/gas.rs :: call_gas_used

function gasUsed() internal view returns (uint64);

Enums

SigningAlg

enum SigningAlg {
    Ed25519Oasis,
    Ed25519Pure,
    Ed25519PrehashedSha512,
    Secp256k1Oasis,
    Secp256k1PrehashedKeccak256,
    Secp256k1PrehashedSha256,
    Sr25519,
    Secp256r1PrehashedSha256,
    Secp384r1PrehashedSha384
}

sha384

Git Source

Hash the input data with SHA-384.

Notes:

  • standard: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf

  • see: @oasisprotocol/oasis-sdk :: precompile/sha2.rs :: call_sha384

function sha384(bytes memory input) view returns (bytes memory output);

Parameters

NameTypeDescription
inputbytesBytes to hash.

Returns

NameTypeDescription
outputbytes48 byte digest.

sha512

Git Source

Hash the input data with SHA-512, according to NIST.FIPS.180-4

Precompile address

0x0100000000000000000000000000000000000101

Warning: SHA-512 vs SHA-512/256 Length-Extension Attacks

SHA-512 is vulnerable to length-extension attacks, which are relevant if you are computing the hash of a secret message. The SHA-512/256 variant is not vulnerable to length-extension attacks.

Gas Cost

115 gas, then 13 gas per word

Example

bytes memory result = sha512(abi.encodePacked("input data"));

Notes:

  • standard: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf

  • see: @oasisprotocol/oasis-sdk :: precompile/sha2.rs :: call_sha512

function sha512(bytes memory input) view returns (bytes memory output);

Parameters

NameTypeDescription
inputbytesBytes to hash.

Returns

NameTypeDescription
outputbytes64 byte digest.

sha512_256

Git Source

Hash the input data with SHA-512/256, according to NIST.FIPS.180-4.

Precompile address

0x0100000000000000000000000000000000000102

Gas cost

115 gas, then 13 gas per word

Example

bytes32 result = sha512_256(abi.encodePacked("input data"));

Warning: SHA-512 vs SHA-512/256 Length-Extension Attacks

SHA-512 is vulnerable to length-extension attacks, which are relevant if you are computing the hash of a secret message. The SHA-512/256 variant is not vulnerable to length-extension attacks.

Notes:

  • standard: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf

  • see: @oasisprotocol/oasis-sdk :: precompile/sha2.rs :: call_sha512_256

function sha512_256(bytes memory input) view returns (bytes32 result);

Parameters

NameTypeDescription
inputbytesBytes to hash.

Returns

NameTypeDescription
resultbytes3232 byte digest.

ParsedSiweMessage

Git Source

struct ParsedSiweMessage {
    bytes schemeDomain;
    address addr;
    bytes statement;
    bytes uri;
    bytes version;
    uint256 chainId;
    bytes nonce;
    bytes issuedAt;
    bytes expirationTime;
    bytes notBefore;
    bytes requestId;
    bytes[] resources;
}

SiweParser

Git Source

Call parseSiweMsg() and provide the EIP-4361 SIWE message. The parser will generate the ParsedSiweMessage struct which you can then use to extract the authentication information in your on-chain contract.

Functions

_hexStringToAddress

Convert string containing hex address without 0x prefix to solidity address object.

function _hexStringToAddress(bytes memory s) internal pure returns (address);

_fromHexChar

function _fromHexChar(uint8 c) internal pure returns (uint8);

_substr

Substring.

function _substr(bytes memory str, uint256 startIndex, uint256 endIndex) internal pure returns (bytes memory);

_parseUint

String to Uint using decimal format. No error handling.

function _parseUint(bytes memory b) internal pure returns (uint256);

_parseField

Parse "NAME: VALUE" in str starting at index i and ending at \n or end of bytes.

function _parseField(bytes calldata str, string memory name, uint256 i) internal pure returns (bytes memory, uint256);

Returns

NameTypeDescription
<none>bytesVALUE and new i, if NAME matched; otherwise empty value and old i.
<none>uint256

_parseArray

Parse bullets, one per line in str starting at i.

function _parseArray(bytes calldata str, uint256 i) internal pure returns (bytes[] memory, uint256);

Returns

NameTypeDescription
<none>bytes[]Array of parsed values and a new i.
<none>uint256

parseSiweMsg

Parse SIWE message.

function parseSiweMsg(bytes calldata siweMsg) internal pure returns (ParsedSiweMessage memory);

Returns

NameTypeDescription
<none>ParsedSiweMessageParsedSiweMessage struct with populated fields from the message.

timestampFromIso

Parse RFC 3339 (ISO 8601) string to timestamp.

function timestampFromIso(bytes memory str) internal pure returns (uint256);

Errors

InvalidAddressLength

Invalid length of the hex-encoded address

error InvalidAddressLength();

InvalidNonce

Invalid length of the nonce

error InvalidNonce();

SubcallReceiptKind

Git Source

enum SubcallReceiptKind {
    Invalid,
    Delegate,
    UndelegateStart,
    UndelegateDone
}

Subcall

Git Source

Interact with Oasis Runtime SDK modules from Sapphire.

State Variables

CONSENSUS_DELEGATE

string private constant CONSENSUS_DELEGATE = "consensus.Delegate";

CONSENSUS_UNDELEGATE

string private constant CONSENSUS_UNDELEGATE = "consensus.Undelegate";

CONSENSUS_WITHDRAW

string private constant CONSENSUS_WITHDRAW = "consensus.Withdraw";

CONSENSUS_TAKE_RECEIPT

string private constant CONSENSUS_TAKE_RECEIPT = "consensus.TakeReceipt";

ACCOUNTS_TRANSFER

string private constant ACCOUNTS_TRANSFER = "accounts.Transfer";

CORE_CALLDATAPUBLICKEY

string private constant CORE_CALLDATAPUBLICKEY = "core.CallDataPublicKey";

CORE_CURRENT_EPOCH

string private constant CORE_CURRENT_EPOCH = "core.CurrentEpoch";

ROFL_IS_AUTHORIZED_ORIGIN

string private constant ROFL_IS_AUTHORIZED_ORIGIN = "rofl.IsAuthorizedOrigin";

SUBCALL

Address of the SUBCALL precompile

address internal constant SUBCALL = 0x0100000000000000000000000000000000000103;

Functions

subcall

Submit a native message to the Oasis runtime layer. Messages which re-enter the EVM module are forbidden: evm.*.

function subcall(string memory method, bytes memory body) internal returns (uint64 status, bytes memory data);

Parameters

NameTypeDescription
methodstringNative message type.
bodybytesCBOR encoded body.

Returns

NameTypeDescription
statusuint64Result of call.
databytesCBOR encoded result.

subcall_static

Submit a read-only native message to the Oasis runtime layer using STATICCALL. Messages which re-enter the EVM module are forbidden: evm.*.

function subcall_static(string memory method, bytes memory body)
    internal
    view
    returns (uint64 status, bytes memory data);

Parameters

NameTypeDescription
methodstringNative message type.
bodybytesCBOR encoded body.

Returns

NameTypeDescription
statusuint64Result of call.
databytesCBOR encoded result.

_subcallWithToAndAmount

Generic method to call {to:address, amount:uint128}.

function _subcallWithToAndAmount(string memory method, StakingAddress to, uint128 value, bytes memory token)
    internal
    returns (uint64 status, bytes memory data);

Parameters

NameTypeDescription
methodstringRuntime SDK method name ('module.Action').
toStakingAddressDestination address.
valueuint128Amount specified.
tokenbytes

Returns

NameTypeDescription
statusuint64Non-zero on error.
databytesModule name on error.

consensusTakeReceipt

Returns a CBOR encoded structure, containing the following possible keys. All keys are optional:

  • shares: u128
  • epoch: EpochTime
  • receipt: u64
  • amount: u128
  • error: {module: string, code: u32}

Keys returned by specific subcalls

  • Delegate will have the error or shares keys.
  • UndelegateStart will have the epoch and receipt keys.
  • UndelegateDone will have the amount key.
function consensusTakeReceipt(SubcallReceiptKind kind, uint64 receiptId) internal returns (bytes memory);

Parameters

NameTypeDescription
kindSubcallReceiptKind1 (Delegate), 2 (UndelegateStart) or 3 (UndelegateDone)
receiptIduint64ID of receipt

_decodeReceiptUndelegateStart

function _decodeReceiptUndelegateStart(bytes memory result) internal pure returns (uint64 epoch, uint64 endReceipt);

_decodeReceiptUndelegateDone

function _decodeReceiptUndelegateDone(bytes memory result) internal pure returns (uint128 amount);

_decodeReceiptDelegate

Decodes a 'Delegate' receipt.

function _decodeReceiptDelegate(uint64 receiptId, bytes memory result) internal pure returns (uint128 shares);

Parameters

NameTypeDescription
receiptIduint64Previously unretrieved receipt.
resultbytesCBOR encoded {shares: u128}.

consensusTakeReceiptDelegate

function consensusTakeReceiptDelegate(uint64 receiptId) internal returns (uint128 shares);

consensusTakeReceiptUndelegateStart

function consensusTakeReceiptUndelegateStart(uint64 receiptId) internal returns (uint64 epoch, uint64 endReceipt);

consensusTakeReceiptUndelegateDone

function consensusTakeReceiptUndelegateDone(uint64 receiptId) internal returns (uint128 amount);

consensusUndelegate

Start the undelegation process of the given number of shares from consensus staking account to runtime account.

function consensusUndelegate(StakingAddress from, uint128 shares) internal;

Parameters

NameTypeDescription
fromStakingAddressConsensus address which shares were delegated to.
sharesuint128Number of shares to withdraw back to us.

consensusUndelegate

function consensusUndelegate(StakingAddress from, uint128 shares, uint64 receiptId) internal;

consensusDelegate

Delegate native token to consensus level.

function consensusDelegate(StakingAddress to, uint128 amount) internal returns (bytes memory data);

Parameters

NameTypeDescription
toStakingAddressConsensus address shares are delegated to.
amountuint128Native token amount (in wei).

consensusDelegate

Delegate native token to consensus level. Requests that the number of shares allocated can be retrieved with a receipt. The receipt will be of ReceiptKind.DelegateDone and can be decoded using decodeReceiptDelegateDone.

function consensusDelegate(StakingAddress to, uint128 amount, uint64 receiptId) internal returns (bytes memory data);

Parameters

NameTypeDescription
toStakingAddressConsensus address shares are delegated to.
amountuint128Native token amount (in wei).
receiptIduint64contract-specific receipt to retrieve result.

consensusWithdraw

Transfer from an account in this runtime to a consensus staking account.

function consensusWithdraw(StakingAddress to, uint128 value) internal;

Parameters

NameTypeDescription
toStakingAddressConsensus address which gets the tokens.
valueuint128Token amount (in wei).

accountsTransfer

Perform a transfer to another account. This is equivalent of payable(to).transfer(value);.

function accountsTransfer(address to, uint128 value) internal;

Parameters

NameTypeDescription
toaddressDestination account.
valueuint128native token amount (in wei).

roflEnsureAuthorizedOrigin

Verify whether the origin transaction is signed by an authorized ROFL instance for the given application.

function roflEnsureAuthorizedOrigin(bytes21 appId) internal view;

Parameters

NameTypeDescription
appIdbytes21ROFL app identifier

_parseCBORPublicKeyInner

function _parseCBORPublicKeyInner(bytes memory in_data, uint256 in_offset)
    internal
    pure
    returns (uint256 offset, CallDataPublicKey memory public_key);

_parseCBORCallDataPublicKey

function _parseCBORCallDataPublicKey(bytes memory in_data)
    internal
    pure
    returns (uint256 epoch, CallDataPublicKey memory public_key);

coreCallDataPublicKey

function coreCallDataPublicKey() internal view returns (uint256 epoch, CallDataPublicKey memory public_key);

coreCurrentEpoch

function coreCurrentEpoch() internal view returns (uint256);

Errors

SubcallError

Raised if the underlying subcall precompile does not succeed

error SubcallError();

ParseReceiptError

There was an error parsing the receipt

error ParseReceiptError(uint64 receiptId);

ConsensusUndelegateError

error ConsensusUndelegateError(uint64 status, string data);

ConsensusDelegateError

error ConsensusDelegateError(uint64 status, string data);

ConsensusTakeReceiptError

error ConsensusTakeReceiptError(uint64 status, string data);

ConsensusWithdrawError

error ConsensusWithdrawError(uint64 status, string data);

AccountsTransferError

error AccountsTransferError(uint64 status, string data);

WrongMapSizeError

Expected map of different size!

error WrongMapSizeError();

TakeReceiptKindOutOfRange

Unknown type of receipt!

error TakeReceiptKindOutOfRange(uint256 receiptKind);

RoflOriginNotAuthorizedForApp

The origin is not authorized for the given ROFL app

error RoflOriginNotAuthorizedForApp();

TokenNameTooLong

Name of token cannot be CBOR encoded with current functions

error TokenNameTooLong();

InvalidReceiptId

Invalid receipt ID

error InvalidReceiptId();

MissingKey

CBOR parser expected a key, but it was not found in the map!

error MissingKey();

IncompleteParse

We expected to have parsed everything, but there are excess bytes!

error IncompleteParse();

CoreCurrentEpochError

Error while trying to retrieve current epoch

error CoreCurrentEpochError(uint64);

CoreCallDataPublicKeyError

Error while trying to retrieve the calldata public key

error CoreCallDataPublicKeyError(uint64);

Structs

CallDataPublicKey

struct CallDataPublicKey {
    bytes32 key;
    bytes32 checksum;
    bytes32[2] signature;
    uint256 expiration;
}

WrappedROSE

Git Source

Inherits: ERC20, ERC20Burnable

Functions

constructor

constructor() ERC20("Wrapped ROSE", "wROSE");

deposit

function deposit() external payable;

withdraw

function withdraw(uint256 amount) external;

receive

receive() external payable;

_deposit

function _deposit() internal;

Events

Deposit

event Deposit(address indexed dst, uint256 wad);

Withdrawal

event Withdrawal(address indexed src, uint256 wad);

hmac_sha512_256_memcpy

Git Source

Copying key buffer failed (identity precompile error?)

error hmac_sha512_256_memcpy();

hmac_sha512_256

Git Source

Implements HMAC using SHA512-256.

https://en.wikipedia.org/wiki/HMAC

function hmac_sha512_256(bytes memory key, bytes memory message) view returns (bytes32);

Parameters

NameTypeDescription
keybytesthe secret key.
messagebytesthe message to be authenticated. #### Example solidity bytes memory key = "arbitrary length key"; bytes memory message = "arbitrary length message"; bytes32 hmac = hmac_sha512_256(key, message)

Constants

Git Source

SHA512_256_BLOCK_SIZE

uint256 constant SHA512_256_BLOCK_SIZE = 128;

PRECOMPILE_IDENTITY_ADDRESS

uint256 constant PRECOMPILE_IDENTITY_ADDRESS = 4;

HMAC_IPAD

bytes32 constant HMAC_IPAD = 0x3636363636363636363636363636363636363636363636363636363636363636;

HMAC_OPAD_XOR_IPAD

bytes32 constant HMAC_OPAD_XOR_IPAD = 0x6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a6a;