Description
Most blockchain functions map well to WASI except for call
/transact
, which is an RPC augmented with the ability to transfer the platform's native token (e.g., Eth) from the caller to the callee. It's possible to do this out-of band, but not efficiently: it'd require making two transactions, passing around receipts, and handling rollbacks/refunds.
As long as we're going the WASI module route, it might be worth adding a single function to the "blockchain" module to support Ethereum-like blockchains:
__wasi_blockchain_transact(
callee_addr: *const u8,
value: u64,
input: *const u8,
input_len: u64,
fd: *mut __wasi_fd_t
) -> __wasi_errno_t;
callee_addr
is a fixed-length byte sequence with length known by the platform. For instance, Ethereum addresses are 20 bytes long.value
is the amount of native token to transfer from the calling account to the calleeinput
/input_len
- a C slice containing the input to the transaction.input_len = 0
for simple balance transfer.fd
- a capability to read the output of the transaction
The errno result would be
- success:
ESUCCESS
- no account at callee address:
EADDRNOTAVAIL
- insufficient funds for value transfer:
ENOBAL
(this one would have to be assigned a number - anything else: application specific
- (running out of computation resources, or gas, is unrecoverable and results in the process aborting)
Upon ESUCCESS
, fd
would be of type SOCKET_STREAM
and have read-only pipe
semantics.
This proposal would support most existing smart contract platforms including those with a synchronous RPC model (e.g. Ethereum, EOS) and those with asynchronous cross-shard RPCs (e.g, Near).
Note: left out of this call function, but perhaps desirable, is the amount of gas
allocated to the sub-transaction. The alternative is to simply give the callee the full amount of remaining gas. One would presumably not call untrusted code, so there should be no need to limit gas for security reasons.