Skip to content

Instantly share code, notes, and snippets.

@Daniel-VDM
Last active September 4, 2020 14:32
Show Gist options
  • Save Daniel-VDM/c3c9fd46980baf26602fc3b4c2f8bf59 to your computer and use it in GitHub Desktop.
Save Daniel-VDM/c3c9fd46980baf26602fc3b4c2f8bf59 to your computer and use it in GitHub Desktop.

Multichain integration

Overview

Multichain is a collection of functions, types, interfaces, and runtimes that can be implemented for any blockchain. Those familiar with the Rosetta spec by Coinbase will note similarities in goals. However, multichain's scope is limited to accounts, contract calls, and sending transactions — there is no block data extraction. Moreover, the chain (Harmony) would have to implement the appropriate functions to Ren's multichain repo as a pull request and undergo their review. The Ren Project notes that once Harmony has integrated with the multichain API, we have the possibility for support in the RenVM.

Context

To help bridge the gap between Harmony and other chains, we must explore ways to integrate with chain agnostic interfaces. Having an API that is standard across multiple chains (notably BTC & ETH) will help reduce the friction of getting assets onto Harmony. This document will provide a high level (but technical) overview of the components needed to integrate with Multichain.

Goals & Non-Goals

What APIs would be available:

What extra components are needed:

  • Localnet with a docker file
  • Supplementary testing account just for localnet (not funded on testnet)
  • Gas price estimate RPC (optional)

What will NOT be built:

  • Staking Compatability
  • Block data extraction
  • UTXO APIs

Implementation Overview

As a reference, we can follow this guide.

Note that we should only rely on imports from the core protocol repo as the go-SDK is subject to change soon.

Communicating with the Harmony network

We will use JSON-RPC 2.0 to communicate with a Harmony node.

We can choose to implement our own requester, or we can re-use solana's RPC requester here as they also use JSON-RPC 2.0.

We will be integrating with 1 shard ONLY (defined as the target-shard). This reduces the complexity of transaction functionalities and should be sufficient for the goals of multichain.

We may choose to add it as an option when creating a Client and propagating it to the TxBuilder (explained in the Account API). Alternatively, we can just hard code the shard to beacon-shard as it has the most assets.

Docker file for Testing

Multichain requires a docker file to run a node for a chain's test. All docker files will get placed here and get triggered from here.

We do not have any easy way to run a localnet like ganache, therefore we will just replicate the debug localnet (from here) using the latest stable binary within a docker image (exposing the target-shard's explorer port) to provide a node for tests. Some of the leg work has been done here & here, however, some integration needs to be done to fit the necessary functionality.

Address API

The interface to implement is EncoderDecoder, which consists of the Encoder and Decoder interfaces.

Note that we should use the Bech-32 addresses (a string) cast as Address and the byte representation of the Bech-32 addresses cast as RawAddress. This way, we should not have to redefine/reimplement the Address and RawAddress types & methods. The alternative is to just use the already implemented ETH addresses here and re-export the Address.

Since we are using the Bech-32 addresses, it should be easy to create a simple address Encoder & Decoder. If we use the built-in ETH address, we do not have to implement a decoder/encoder — all we have to do is re-export it (similar to what Celo has done here).

Account API

The interfaces to implement are: Tx, TxBuilder, and Client.

Note that for signing transactions, we are always in post EIP115 epoch, therefore we must always use the EIP115 signer found here.

For the Tx interface, the Hash, From, To, Value, Nonce, and Payload methods should be easy to implement with a wrapper around the Harmony Transaction object. The Sighashes method's content can be found here. The Sign method's implementation can be found here & here. Lastly, the Serialize method is simply the RLP encoding to bytes to be submitted to the mem pool (example here).

Note that for signing transactions, we are always in post EIP115 epoch, therefore we can always use the EIP115 signer found here. Homestead signers are to be ignored. For the ChainID required by the EIP115 signer, we can store it as an attribute of the Tx object and set it upon building a new transaction.

For the TxBuilder interface, we only have to implement the BuildTx method. Note that we must include the Chain ID for the EIP115 signer; this can be fetched from the node's metadata within the BuildTx method. We may also want to include an additional method for TxBuilder to fetch the appropriate nonce for the BuildTx param.

For the Client interface, the Tx method is simply a getTransactionByHash RPC call. The SubmitTx method is not clear as to if it should block until confirmation of tx or not. Since most APIs do not block on the submission of a transaction, we should implement it as such.

Contract API

The interface to implement is Caller. The only method to implement is CallContract. Note that the CallData could be a byte or marshaled version of the call data struct used by the call RPC.

Note that we should keep the address consistent. Our RPC layer takes in hex addresses instead of the Bech-32 addresses for the CallArgs. For consistency, we may want to take the call arguments in multichain as Bech-32 (from Address API) and convert them appropriately for the RPC call.

Also note that it may be worth it to implement the CallContract under the Client object from the Account API as some state variables may be shared.

Gas API

The interface to implement is Estimator. The only method to implement is EstimateGasPrice. Note that we currently do not have a way to estimate the gas price. We can either hard code some value in multichain (citing 5sec block time as an excuse), or we can implement an RPC to get the average gas price in the mem-pool and call that as part of the EstimateGasPrice method.

Final Touchups

Add ONE as a supported asset here & ensure tests pass for ALL supported chains.

Milestones

Discription Target Date
Address API 9/3
Docker Localnet for Tests 9/4
Account API TBD
Gas API [+ Gas Price Estimator RPC] TBD
Contract API + Final Touchups TBD

Current Scoping & Timeline

This is where updates will be posted regarding current progress & hurdles.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment