Skip to content

Latest commit

 

History

History
111 lines (97 loc) · 5.06 KB

NEW_CHAINS.md

File metadata and controls

111 lines (97 loc) · 5.06 KB

Implementing a new chain

This is a high-level guide to implementing a library for a new chain.

Implementing Inputs

An input consumes some TXO referenced by its ID.

  1. Select or create a struct to be your TxoIdentifier
  2. This is the unique in-protocol identifier for a TXO.
  3. In Bitcoin this is bitcoins::types::txin::BitcoinOutpoint.
  4. Add the marker trait: impl coins_core::types::tx::TxoIdentifier
  5. Implement a type to be your Input
  6. This represents the input TXOs consumed by a transaction.
  7. This could be the same as TxoIdentifier, depending on your protocol.
  8. In Bitcoin this is bitcoins::types::txin::BitcoinInput.
  9. Add the marker trait: impl coins_core::types::tx::Input
  10. Associate your TxoIdentifier type

Implementing Outputs

An output creates a new TXO with some value owned by some payee.

  1. Select or create a struct to be your RecipientIdentifier
  2. This is used to identify payees in-protocol.
  3. In Bitcoin this is bitcoins::types::script::ScriptPubkey
  4. impl coins_core::types::tx::RecipientIdentifier on your struct
  5. Select or create a type to be your Value
  6. This type represents how the in-protocol value of a TXO.
  7. In Bitcoin this is u64.
  8. In Ethereum-based TXO chains this is often a U256 struct.
  9. impl coins_core::types::tx::Value on your struct.
  10. Implement a type to be your Output
  11. This represents the output TXOs created by a transaction.
  12. In Bitcoin this is bitcoins::types::txout::BitcoinInput.
  13. Add the trait: impl coins_core::types::tx::Output
  14. Associate your Value and RecipientIdentifier types.

Implementing Transactions

A transaction is a list of inputs and outputs. It provides methods to access its properties, as well as calculate its signature hash.

  1. Define the hash function used by your TX:
  2. We do this so that your TX can use arbitray hashes, while keeping type safety.
  3. Define a Digest type that represents the output of your hash functions. 1. Bitcoin uses [u8; 32]
  4. Define a MarkedDigest type (see coins_core::hashes::marked) for your TXIDs.
  5. Define a MarkedDigestWriter type that can output Digest and MarkedDigest types. 1. This must implement std::io::Write. 1. Bitcoin uses coins_core::hashes::hash256::Hash256Writer
  6. Define an Error type to handle your errors.
  7. This should contain any errors that can occur while interacting with your transaction.
  8. See bitcoins::types::transactions::TxError for an example.
  9. Define a SighashArgs type for your transaction.
  10. This struct should carry all the information needed to calculate the hash of your transaction that is signed.
  11. Define a Transaction struct.
  12. impl coins_core::ser::Ser on your Transaction.
  13. If necessary, create a new Error type (see an example in bitcoin/types/transaction.rs)
  14. This ensures that your tx can be serialized easily.
  15. It is used in the default txid implementation.
  16. impl coins_core::types::tx::Transaction on your Transaction
  17. Associate your Error, Digest, HashWriter, TXID, SighashArgs, Input, and Output types.
  18. This is a simple interface for accessing inputs, outputs, and other tx info.
  19. If your transaction type does not have a version or a locktime, you may implement these as NOPs.

Implementing the Encoder

An AddressEncoder tranlates between protocol-facing, and human-facing datastructures. Typically this means managing the relationship between addresses and their in-protocol counterparts.

  1. Define an Error type. It's fine to reuse a previouse Error here.
  2. Create a type to be your Address
  3. This represents the human-facing payee, and can be translated to a RecipientIdentifier
  4. In Bitcoin this is an enum wrapper around a String.
  5. Create a type to be your Encoder
  6. impl coins_core::enc::AddressEncoder on your Encoder
  7. encode_address transforms a RecipientIdentifier to an Address.
  8. decode_address transforms an Address to a RecipientIdentifier.
  9. string_to_address transforms a &str to an Address
  10. Associate your Address, RecipientIdentifier, and EncoderError types.

Implementing a Builder

  1. Create a struct to be your Builder.
  2. impl coins_core::builder::TxBuilder for your Builder type
  3. Associate your Transaction and AddressEncoder from previous steps.
  4. Feel free to leave version and locktime as NOPs if unsupported by your protocol.

Implementing a Network

The Network ensures type consistency across all previous types. For example, it guarantees that your Encoder, Builder, and TxOut use the same RecipientIdentifier.

  1. Define a new Error type. It's fine to reuse a previous Error here.
  2. Define a Network type.
  3. impl coins_core::nets::Network on your Network.
  4. Associate your Error type.
  5. Associate your TxIn, TxOut, and Transaction types from previous steps.
  6. Associate your Address, RecipientIdentifier, and AddressEncoder types.
  7. Associate your Builder type.