public static UnlockScripts ProduceSingleUnlockScript(this Signature sig) => (UnlockScripts)new[] { ScriptToken.CreateToken(sig.ToBase58()), };
public static LockScripts ProduceSingleLockScript(this PublicKey pubKey) => (LockScripts)new[] { ScriptToken.CreateToken(pubKey.ToBase58()), ScriptToken.CreateToken(OpCode.CheckSignature), };
public static bool CanUnlock(this Transaction tran, TxInput input, TxOutput output) { try { var scripts = input.UnlockScripts + output.LockScripts; var result = scripts.TryExecuteAsync(tran); if (!result) return false; } catch (Exception) { return false; } return true; }
private BlockHead GenerateBlock() { ... var minerTxOut = new TxOutput { LockScripts = this.MinerWallet.PublicKey.ProduceSingleLockScript(), Value = this.BlockChain.RewardOfBlock + fee }; var minerTx = new Transaction { Outputs = new[] { minerTxOut }, }; ... }
private bool ValidateTx(Transaction tx) { ... foreach (var intx in tx.InputTxs) { ... if (!verifyTx.CanUnlock(intx, output)) return false; } ... }
public Transaction SendMoney(Engine engine, Transaction utxo, int index, IWallet receiver, int value, int fee = 0, uint lockTime = 0) { var total = utxo.Outputs[index].Value; var change = total - value - fee; var mainOutput = new TxOutput { LockScripts = receiver.PublicKey.ProduceSingleLockScript(), Value = value }; var changeOutput = new TxOutput { LockScripts = this.PublicKey.ProduceSingleLockScript(), Value = change }; return this.SendMoney(engine, lockTime, new[] { new Utxo(utxo, index) }, mainOutput, changeOutput); }
public Transaction SendMoney(Engine engine, uint lockTime, Utxo[] utxos, params TxOutput[] outputs) { var inputTxs = utxos .Select(_ => new TxInput { PrevTxHash = _.Tx.Hash, PrevTxIndex = _.Index }) .ToArray(); var tx = new Transaction { InputTxs = inputTxs, Outputs = outputs, LockTime = lockTime, }; var sigList = new Signature[tx.InputTxs.Length]; for (int i = 0; i < tx.InputTxs.Length; i++) { var utxoEnt = utxos[i]; sigList[i] = this.signAlgo.Sign( new[] { (byte[])tx.GetLockHash() }, this.FindPrivateKey(utxoEnt.Tx.Outputs[utxoEnt.Index].LockScripts)); } for (int i = 0; i < tx.InputTxs.Length; i++) { tx.InputTxs[i].UnlockScripts = sigList[i].ProduceSingleUnlockScript(); } engine.AttachTx(tx); return tx; }
protected abstract PrivateKey FindPrivateKey(LockScripts lockScripts); protected abstract bool ContainPubKey(LockScripts lockScripts);
public class DeterministicWallet : BaseWallet { protected override PrivateKey FindPrivateKey(LockScripts lockScripts) { var idx = this.usedPublicKeys.FindIndex(_ => lockScripts.Contains(new ScriptToken(_.ToBase58()))); if (idx == -1) throw new KeyNotFoundException("cannot find corresponding public key"); return this.usedPrivateKeys[idx]; } protected override bool ContainPubKey(LockScripts lockScripts) { return this.usedPublicKeys.Any(_ => lockScripts.Contains(new ScriptToken(_.ToBase58()))); } }
public class SimpleWallet : BaseWallet { protected override PrivateKey FindPrivateKey(LockScripts lockScripts) { if (!lockScripts.Contains(new ScriptToken(this.PublicKey.ToBase58()))) throw new KeyNotFoundException("cannot find corresponding public key"); return this.PrivateKey; } protected override bool ContainPubKey(LockScripts lockScripts) { return lockScripts.Contains(new ScriptToken(this.PublicKey.ToBase58())); } }
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8