UNPKG

hamilton

Version:

Tools and utilities for interacting with Project Hamilton OpenCBDC atomizer and 2pc environments

217 lines (176 loc) 10 kB
CBDC ==== This is a pure JS node module which reads and writes the binary transaction and watchtower packet formats used in CBDC-universe0. It also contains utilities to calculate UHS and transaction hashes from output data. The following is a breakdown of sections and classes for this cbdc-module: ## Crypto - Address - constructor(script_type, pubHex) - ```a new Address Object``` - script_type - {Number} representing the script type of the address - pubHex - {String} represents valid 32 byte hexadecimal string - getAddress() - returns {String} ```represented the bech32 encoding version of a publickey e.g. ``` - decodeAddress() - returns {Object} ```with fields script_type (string representing) and pubHex (hex string of public key)``` - static decodeFromAddressString(address) - returns ```{Object} with fields script_type {Number} and pubHex {String} (hexdecimal string of public key)``` - Publickey - constructor(secretKeyData) - ```returns a new Publickey object``` - secretKeyData - ```{String} a valid 32 byte hexadecimal string``` - static fromPrivateKeyData(secretKeyData) - secretKeyData - ```{String} a valid 32 byte hexadecimal string``` - toBuffer() - ```returns {Buffer} 32 byte buffer publickey``` - Secretkey - contructor(randBytes) - ```returns new SecretKey with randBytes provided as random seed (if provided), otherwise it creates random key from random secrety bytes``` - randBytes - {Buffer} optional 32 bytes used to seed for privatekey, otherwise another random - toString() - ```returns {String} valid hexadecimal string of privatekey``` - toBuffer() - ```returns {Buffer} valid 32 byte Buffer for privatekey``` - static fromHex(secretKeyHex)- ``` returns {SecretKey} from secretKeyHex``` - secretKeyHex - valid 32 byte hexadecimal string for privateKey - toHex() - ```returns hexadecimal representation of privateKey``` ## Networking * Networking - broadcastTx(port, host, signedTxHex) - ```broadcast a signedTxBuf to a sentinel server at host {host} and port {port} number``` - port - {number} port number of host - host - {string} hostname url to send signedTx - signedTxHex - {string} a valid hexadecimal encoded transaction that has been signed ## Transaction - Input - constructor(tx_hash, index, witnessProgramCommitment, value) ```returns new Input Object Type``` - tx_hash - {String} valid hexadecimal string for transaction hash this input references - index - {number} index position of the input for tx - witnessProgramCommitment {String} - witness commitment for this input - value {number} - the number of dollar units this input is worth - writeInputToBuffer() - ```returns Buffer representation as buffer type``` - getUHSHash() - ```returns {Buffer} Universal Hash Set hash of the input e.g. concatentation of [txid, index, witnessProgramCommitment, value] into bytes``` e.g. - toString() - ```returns {String} representing valid input``` ## Utils - Utility Methods CBDC module - sign(secretKey, message) - ```returns signature that signed message {message} with privateKey {privateKey}``` - secretKey - {String} - 32 byte hexadecimal string - message - {String} - message that is signed - verify(publicKey, message, signature) ```returns true or false whether the produced signature is validly signed publicKey``` - publicKey - 32 byte hexadecimal string - message - message to verify was signed - signature - {String} signature to verify validly signed message against public key message pair Note: A Universal Hash Set Hash is used to identify a specfic (UTXO) within the cbdc-universe system it is a concatenation of a txid, a 64 bit encoded index of previous tx, a witnessProgramCommitment, and a 64 bit encoded value for that encoded output - Output - constructor(witnessProgramCommitment, value) ```returns new Output Object type``` - witnessProgramCommitment - {String} - value - {Number} - writeOutputToBuffer() - ```returns a Buffer representation of this output in raw bytes``` - static fromOutputData(pubHex, value) - ```returns a new {Output} from publicKey and value provided``` - pubHex - {String} - value - {Number} - toString() - ```returns {String} string representation of Output``` - Transaction - constructor(inputs, outputs, witnesses) - ```returns new {Transaction} object``` - inputs - Array{Input} - outputs - Array{Output} - witnesses - Array of witness object - toHex() - ```returns {String} hexadecimal string of the unsigned raw transaction``` - getTxid() - ```returns {String} returns hexadecimal string of transaction id (txid)``` - sign(secretKey) - ```returns {Buffer} signed tx in bytes``` - static txFromHex(rawHex) - ```returns {Transaction} object from the provided rawTx``` - rawHex - valid hexadecimal string represents a valid tx ## Special Notes BigInt is used everywhere throughout this module, that may pose problems in using toJson() methods or serializing for output ## Example Usage The following are example interactions. - Address ``` const addr = new Address('00', '3ad8f015f9212f8262248af4cf4cc39907d0215fdde14507f8bc09ad5836bbe9') console.log(addr.getAddress()); usd1qqad3uq4lysjlqnzyj90fn6vcwvs05pptlw7z3g8lz7qnt2cx6a7jty6gr5 console.log(addr.decodeAddress()); { script_type: 0, pubHex: 3ad8f015f9212f8262248af4cf4cc39907d0215fdde14507f8bc09ad5836bbe9 } ``` - Publickey ``` const pub = new Publickey('e00b5c3d80899217a22fea87e7337907203df8a1efebd4d2a8773c8f629fff36') console.log(pub.toBuffer()); ``` - Secretkey ``` const secKey = new SecretKey(Buffer.from(parseInt(Math.round(Math.random() * 10)), 'hex')); secKey.toString(); secKey.toBuffer(); ``` - Networking ``` let network = require('./networking/broadcast'); const txBuf = new Transaction(); Networking.broadcast(5555, '127.0.0.1', Buffer.from(tx.toHex(), 'hex')) ``` - Transaction ``` const input = new Input('9f981e64afc0fc56a0d7b355cd9eba36f3d19507088713b1f73afc5bf301a44e', 0, '70cd87ebaaa0d2d059dccaceeb7f9f823a5791d60b00aef9d9573f1fbf91ca29', 200) const output = new Output('81b095a242974d9f4e98ca18b468b8e644e4168380a035b3d66bc279b36c6510', 200) const tx = new Transaction([input], [output], []); tx.sign('e00b5c3d80899217a22fea87e7337907203df8a1efebd4d2a8773c8f629fff36') console.log(tx.getTxid()); 12e01dfa90358fd203da3acbbe105b1ed2d249cd8e601ed919f4b8b2a99cbb02 console.log(tx); 01000000000000009f981e64afc0fc56a0d7b355cd9eba36f3d19507088713b1f73afc5bf301a44e000000000000000070cd87ebaaa0d2d059dccaceeb7f9f823a5791d60b00aef9d9573f1fbf91ca29c800000000000000010000000000000081b095a242974d9f4e98ca18b468b8e644e4168380a035b3d66bc279b36c6510c80000000000000001000000000000006100000000000000003ad8f015f9212f8262248af4cf4cc39907d0215fdde14507f8bc09ad5836bbe901986cc97272bdb7624a824afcef76936b8f945e55d6e8479b95c81298e77b42d5a255e8529fc2f0d90743e7f9997a7159b6121105c7ec9b9252da992f34611f ``` - Constructing, signing and broacasting tx to sentinel ``` const secretKey = 'e00b5c3d80899217a22fea87e7337907203df8a1efebd4d2a8773c8f629fff36'; const input = new Input('9f981e64afc0fc56a0d7b355cd9eba36f3d19507088713b1f73afc5bf301a44e', 0, 70cd87ebaaa0d2d059dccaceeb7f9f823a5791d60b00aef9d9573f1fbf91ca29, 200) const output = new Output('81b095a242974d9f4e98ca18b468b8e644e4168380a035b3d66bc279b36c6510', 200) const tx = new Transaction([input], [output], []); tx.sign(secretKey); Networking.broadcast(5555, '127.0.0.1', Buffer.from(tx.toHex(), 'hex')) ``` - Signing and Verifying ``` const secretKey = "e00b5c3d80899217a22fea87e7337907203df8a1efebd4d2a8773c8f629fff36"; const publicKey = "3ad8f015f9212f8262248af4cf4cc39907d0215fdde14507f8bc09ad5836bbe9"; const sha256 = function () {...}; const message = 'onomatopoeia'; const sig = utils.sign(secretKey, message); utils.verify(publicKey, Buffer.from(sha256(message), 'hex'), sig); ``` ## Sample Data ### Secret and Related Public Key ``` secret key: e00b5c3d80899217a22fea87e7337907203df8a1efebd4d2a8773c8f629fff36 public key: 3ad8f015f9212f8262248af4cf4cc39907d0215fdde14507f8bc09ad5836bbe9 ``` ### Signed Transaction ``` 01000000000000009f981e64afc0fc56a0d7b355cd9eba36f3d19507088713b1f73afc5bf301a44e000000000000000070cd87ebaaa0d2d059dccaceeb7f9f823a5791d60b00aef9d9573f1fbf91ca29c800000000000000010000000000000081b095a242974d9f4e98ca18b468b8e644e4168380a035b3d66bc279b36c6510c80000000000000001000000000000006100000000000000003ad8f015f9212f8262248af4cf4cc39907d0215fdde14507f8bc09ad5836bbe901986cc97272bdb7624a824afcef76936b8f945e55d6e8479b95c81298e77b42d5a255e8529fc2f0d90743e7f9997a7159b6121105c7ec9b9252da992f34611f ``` ### Signed Transaction Decoded ``` Tx { inputs: [ { tx_hash: '9f981e64afc0fc56a0d7b355cd9eba36f3d19507088713b1f73afc5bf301a44e', index: 0n, witness_program_commitment: '70cd87ebaaa0d2d059dccaceeb7f9f823a5791d60b00aef9d9573f1fbf91ca29', value: 200n } ], outputs: [ { witness_program_commitment: '81b095a242974d9f4e98ca18b468b8e644e4168380a035b3d66bc279b36c6510', value: 200n } ], witnesses: [ { witness_length: 97n, script_type: 0, pubkey: '3ad8f015f9212f8262248af4cf4cc39907d0215fdde14507f8bc09ad5836bbe9', signature: '01986cc97272bdb7624a824afcef76936b8f945e55d6e8479b95c81298e77b42d5a255e8529fc2f0d90743e7f9997a7159b6121105c7ec9b9252da992f34611f' } ] } ``` ### Testing * Install `mocha` with `npm install mocha` or `npm i -g mocha` * Run the command `npm test` from the root directory ### Contributions * Please submit a pull request with your reasoning so it will be discussed and reviewed