public static void Refund() { var inputs = new List <CoinReference> { new CoinReference() { PrevHash = new UInt256("0x44d5a5ef32c8ec780de59ca59cb799efd1bf3051d9a2c94a2b1d13af34abe7ca".Remove(0, 2).HexToBytes().Reverse().ToArray()), PrevIndex = 0 } }.ToArray(); var outputs = new List <TransactionOutput> { new TransactionOutput() { AssetId = Blockchain.UtilityToken.Hash, //Asset Id, this is GAS ScriptHash = ScriptHash, //CGAS 地址 Value = new Fixed8((long)(9.99 * (long)Math.Pow(10, 8))) } }.ToArray(); Transaction tx = null; var applicationScript = new byte[0]; using (ScriptBuilder sb = new ScriptBuilder()) { sb.EmitAppCall(ScriptHash, "refund", User); sb.Emit(OpCode.THROWIFNOT); applicationScript = sb.ToArray(); } tx = new InvocationTransaction { Version = 0, Script = applicationScript, Outputs = outputs, Inputs = inputs, Attributes = new TransactionAttribute[] { new TransactionAttribute { Usage = TransactionAttributeUsage.Script, Data = User.ToArray()//附加人的 Script Hash } } }; //Open wallet var wallet = new Neo.Wallets.NEP6.NEP6Wallet(new WalletIndexer("Index_0001E240"), "1.json"); try { wallet.Unlock("11111111"); } catch (Exception) { Console.WriteLine("password error"); } //Sign in wallet 生成附加人的签名 var context = new ContractParametersContext(tx); var additionalSignature = new byte[0]; foreach (UInt160 hash in context.ScriptHashes) { if (hash == User) { WalletAccount account = wallet.GetAccount(hash); if (account?.HasKey != true) { continue; } KeyPair key = account.GetKey(); additionalSignature = context.Verifiable.Sign(key); } } var additionalVerificationScript = new byte[0]; using (ScriptBuilder sb = new ScriptBuilder()) { sb.EmitPush(additionalSignature); additionalVerificationScript = sb.ToArray(); } var verificationScript = new byte[0]; using (ScriptBuilder sb = new ScriptBuilder()) { sb.EmitPush(2); sb.EmitPush("1"); verificationScript = sb.ToArray(); } var witness = new Witness { InvocationScript = verificationScript, VerificationScript = Blockchain.Singleton.Store.GetContracts().TryGet(ScriptHash).Script }; var additionalWitness = new Witness { InvocationScript = additionalVerificationScript, VerificationScript = UserScript }; var witnesses = new Witness[2] { witness, additionalWitness }; tx.Witnesses = witnesses.ToList().OrderBy(p => p.ScriptHash).ToArray(); Verify(tx); }
public static void Refund() { var inputs = new List <CoinReference> { new CoinReference() { PrevHash = new UInt256("0xdb4c4f1a17b365a68497ef0e118db89b827db24f67ee71d317d38c68c84424ef".Remove(0, 2).HexToBytes().Reverse().ToArray()), PrevIndex = 0 //1 } }.ToArray(); var outputs = new List <TransactionOutput> { new TransactionOutput() { AssetId = Blockchain.UtilityToken.Hash, //Asset Id, this is GAS ScriptHash = SgasAddress, //SGAS 地址 Value = new Fixed8((long)(1 * (long)Math.Pow(10, 8))) //Value } }.ToArray(); Transaction tx = null; var applicationScript = new byte[0]; using (ScriptBuilder sb = new ScriptBuilder()) { sb.EmitAppCall(ScriptHash, "refund", User); sb.Emit(OpCode.THROWIFNOT); applicationScript = sb.ToArray(); } tx = new InvocationTransaction { Version = 0, Script = applicationScript, Outputs = outputs, Inputs = inputs, Attributes = new TransactionAttribute[] { new TransactionAttribute { Usage = TransactionAttributeUsage.Script, Data = User.ToArray()//附加人的 Script Hash } } }; if (tx == null) { Console.WriteLine("Create Transaction Failed"); Console.ReadLine(); return; } //Open wallet var wallet = new Neo.Implementations.Wallets.NEP6.NEP6Wallet("0.json"); try { wallet.Unlock("1"); } catch (Exception) { Console.WriteLine("password error"); } //Sign in wallet 生成附加人的签名 var context = new ContractParametersContext(tx); var additionalSignature = new byte[0]; foreach (UInt160 hash in context.ScriptHashes) { if (hash == User) { WalletAccount account = wallet.GetAccount(hash); if (account?.HasKey != true) { continue; } KeyPair key = account.GetKey(); additionalSignature = context.Verifiable.Sign(key); } } var additionalVerificationScript = new byte[0]; using (ScriptBuilder sb = new ScriptBuilder()) { sb.EmitPush(additionalSignature); additionalVerificationScript = sb.ToArray(); } var verificationScript = new byte[0]; using (ScriptBuilder sb = new ScriptBuilder()) { sb.EmitPush(2); sb.EmitPush("1"); verificationScript = sb.ToArray(); } var witness = new Witness { InvocationScript = verificationScript, VerificationScript = Blockchain.Default.GetContract(ScriptHash).Script }; var additionalWitness = new Witness { InvocationScript = additionalVerificationScript, VerificationScript = UserScript }; var witnesses = new Witness[2] { witness, additionalWitness }; tx.Scripts = witnesses.ToList().OrderBy(p => p.ScriptHash).ToArray(); try { tx = Transaction.DeserializeFrom(tx.ToArray()); } catch (Exception) { Console.WriteLine("Invalid Transaction Format"); } if (tx.Verify(new List <Transaction> { tx })) { Console.WriteLine("Verify Transaction: True"); Console.WriteLine("Raw Transaction:"); Console.WriteLine(tx.ToArray().ToHexString()); //Console.WriteLine(tx.ToJson()); //Then Call neo-cli API:sendrawtransaction in postman. } else { Console.WriteLine("Verify Transaction: False"); } }