/// <summary> /// Create SLP Token MINT Output Script /// </summary> /// <param name="tokenId"></param> /// <param name="mintBatonVOut"></param> /// <param name="mintQuantity"></param> /// <returns></returns> public static Script.Script CreateMintScript(byte[] tokenId, byte mintBatonVOut, ulong mintQuantity) { if (tokenId.Length != 32) { throw new ArgumentException( "Invalid tokenId! Expected 32 bytes, received " + tokenId.Length + " bytes."); } if (mintBatonVOut == 1) { throw new ArgumentException( "Invalid mintBatonVOut! Expected 0 (create no baton), or 1-255 (vout), but received 1."); } // header var byteData = GetHeaderBytes(); /* After Header: * <transaction_type: 'MINT'> (4 bytes, ascii) * <token_id> (32 bytes) * <mint_baton_vout> (0 bytes or 1 byte between 0x02-0xff) * <additional_token_quantity> (8 byte integer) */ byteData = byteData.Concat(ScriptBuilder.GetOpPushForLength(4)).Concat("MINT".Select(x => (byte)x)); byteData = byteData.Concat(ScriptBuilder.GetOpPushForLength(32)).Concat(tokenId); byteData = mintBatonVOut == 0 ? byteData.Concat(ScriptBuilder.GetOpPushForLength(0, false)) : byteData.Concat(ScriptBuilder.GetOpPushForLength(1)).Concat(new[] { mintBatonVOut }); byteData = byteData.Concat(ScriptBuilder.GetOpPushForLength(8)).Concat(BitConverter.GetBytes(mintQuantity)); return(ScriptBuilder.CreateOutputOpReturn(byteData.ToArray())); }
/// <summary> /// Create SLP Token GENESIS Output Script /// </summary> /// <param name="ticker"></param> /// <param name="name"></param> /// <param name="documentUrl"></param> /// <param name="documentHash"></param> /// <param name="decimals"></param> /// <param name="mintBatonVOut"></param> /// <param name="mintQuantity"></param> /// <returns></returns> public static Script.Script CreateGenesisScript(byte[] ticker, byte[] name, byte[] documentUrl, byte[] documentHash, byte decimals, byte mintBatonVOut, ulong mintQuantity) { // header var byteData = GetHeaderBytes(); /* After Header: * <transaction_type: 'GENESIS'> (4 bytes, ascii) * <token_ticker> (0 to ∞ bytes, suggested utf-8) * <token_name> (0 to ∞ bytes, suggested utf-8) * <token_document_url> (0 to ∞ bytes, suggested ascii) * <token_document_hash> (0 bytes or 32 bytes) * <decimals> (1 byte in range 0x00-0x09) * <mint_baton_vout> (0 bytes, or 1 byte in range 0x02-0xff) * <initial_token_mint_quantity> (8 byte integer) */ if (documentHash.Length != 0 && documentHash.Length != 32) { throw new ArgumentException("Invalid TokenDocumentHash! Expected either 0 or 32 bytes, but received " + documentHash.Length + " bytes."); } if (0 < decimals || decimals > 9) { throw new ArgumentException("Invalid digits after decimal! Expected 0-9 inclusive, but received " + (int)decimals + "."); } if (mintBatonVOut == 1) { throw new ArgumentException( "Invalid mintBatonVOut! Expected 0 (create no baton), or 1-255 (vout), but received 1."); } byteData = byteData.Concat(ScriptBuilder.GetOpPushForLength(7)).Concat("GENESIS".Select(x => (byte)x)); byteData = byteData.Concat(ScriptBuilder.GetOpPushForLength((uint)ticker.Length, false)).Concat(ticker); byteData = byteData.Concat(ScriptBuilder.GetOpPushForLength((uint)name.Length, false)).Concat(name); byteData = byteData.Concat(ScriptBuilder.GetOpPushForLength((uint)documentUrl.Length, false)) .Concat(documentUrl); byteData = byteData.Concat(ScriptBuilder.GetOpPushForLength((uint)documentHash.Length, false)) .Concat(documentHash); byteData = byteData.Concat(ScriptBuilder.GetOpPushForLength(1)).Concat(new[] { decimals }); byteData = mintBatonVOut == 0 ? byteData.Concat(ScriptBuilder.GetOpPushForLength(0, false)) : byteData.Concat(ScriptBuilder.GetOpPushForLength(1)).Concat(new[] { mintBatonVOut }); byteData = byteData.Concat(ScriptBuilder.GetOpPushForLength(8)).Concat(BitConverter.GetBytes(mintQuantity)); return(ScriptBuilder.CreateOutputOpReturn(byteData.ToArray())); }
public static Script.Script CreateCommitScript(byte[] tokenId, byte[] forBitcoinBlockHash, ulong blockHeight, byte[] tokenTransactionMerkleRoot, string tokenTransactionSetUrl) { // token_id must be 32 bytes if (tokenId.Length != 32) { throw new ArgumentException( "Invalid tokenId! Expected 32 bytes, received " + tokenId.Length + " bytes."); } // for_bitcoin_block_hash must be 32 bytes if (forBitcoinBlockHash.Length != 32) { throw new ArgumentException("Invalid forBitcoinBlockHash! Expected 32 bytes, received " + forBitcoinBlockHash.Length + " bytes."); } // token_ must be 32 bytes if (tokenTransactionMerkleRoot.Length != 32) { throw new ArgumentException("Invalid tokenTransactionMerkleRoot! Expected 32 bytes, received " + tokenTransactionMerkleRoot.Length + " bytes."); } // header var byteData = GetHeaderBytes(); /* After Header: * <transaction_type: 'COMMIT'> (6 bytes, ascii) * <token_id> (32 bytes) * <for_bitcoin_block_hash> (32 bytes) * <block_height> (8 byte integer) * <token_txn_set_hash> (32 bytes) * <txn_set_data_url> (0 to ∞ bytes, ascii) * [to be determined] */ byteData = byteData.Concat(ScriptBuilder.GetOpPushForLength(5)).Concat("COMMIT".Select(x => (byte)x)); byteData = byteData.Concat(ScriptBuilder.GetOpPushForLength(32)).Concat(tokenId); byteData = byteData.Concat(ScriptBuilder.GetOpPushForLength(32)).Concat(forBitcoinBlockHash); byteData = byteData.Concat(ScriptBuilder.GetOpPushForLength(8)).Concat(BitConverter.GetBytes(blockHeight)); byteData = byteData .Concat(ScriptBuilder.GetOpPushForLength((ulong)Encoding.ASCII.GetByteCount(tokenTransactionSetUrl), false)).Concat(Encoding.ASCII.GetBytes(tokenTransactionSetUrl)); return(ScriptBuilder.CreateOutputOpReturn(byteData.ToArray())); }
/// <summary> /// Create SLP Token SEND Output Script /// </summary> /// <param name="tokenId"></param> /// <param name="tokenOutputQuantities"></param> /// <returns></returns> public static Script.Script CreateSendScript(byte[] tokenId, ulong[] tokenOutputQuantities) { // header var byteData = GetHeaderBytes(); /* After Header: * <transaction_type: 'SEND'> (4 bytes, ascii) * <token_id> (32 bytes) * <token_output_quantity1> (required, 8 byte integer) * <token_output_quantity2> (optional, 8 byte integer) * ... * <token_output_quantity19> (optional, 8 byte integer) * */ if (tokenId.Length != 32) { throw new ArgumentException( "Invalid tokenId! Expected 32 bytes, received " + tokenId.Length + " bytes."); } if (tokenOutputQuantities.Length < 1 || tokenOutputQuantities.Length > 19) { throw new ArgumentException("Invalid tokenOutputQuantities! Expected 1-19 outputs, received " + tokenOutputQuantities.Length + " outputs."); } byteData = byteData.Concat(ScriptBuilder.GetOpPushForLength(4)).Concat("SEND".Select(x => (byte)x)); byteData = byteData.Concat(ScriptBuilder.GetOpPushForLength(32)).Concat(tokenId); byteData = tokenOutputQuantities.Aggregate(byteData, (current, tokenOutputQuantity) => current.Concat(ScriptBuilder .GetOpPushForLength(8) .Concat(BitConverter.GetBytes(tokenOutputQuantity)))); return(ScriptBuilder.CreateOutputOpReturn(byteData.ToArray())); }