private void setupCoinReferenceWithVals(CoinReference coinRef, out UInt256 prevHashVal, out ushort prevIndexVal) { prevHashVal = new UInt256(TestUtils.GetByteArray(32, 0x42)); prevIndexVal = 22; coinRef.PrevHash = prevHashVal; coinRef.PrevIndex = prevIndexVal; }
public CustomTransaction(TransactionType type) : base(type) { Version = 1; Inputs = new CoinReference[0]; Outputs = new TransactionOutput[0]; Attributes = new TransactionAttribute[0]; }
/// <summary> /// INIT HISTORY OF TRANSACTIONS /// </summary> /// <param name="scriptHash"></param> /// <param name="value"></param> /// <param name="inputAmount"></param> public static void InitTransactionContext(string scriptHash, int value) { Transaction initialTransaction = new CustomTransaction(TransactionType.ContractTransaction); Transaction currentTransaction = new CustomTransaction(TransactionType.ContractTransaction); TransactionOutput transactionOutput; CoinReference coinRef; /** CREATE FAKE PREVIOUS TRANSACTION */ transactionOutput = new TransactionOutput { ScriptHash = UInt160.Parse(scriptHash), Value = new Fixed8(value), AssetId = UInt256.Parse(NEO_ASSET_ID) }; initialTransaction.Outputs = new TransactionOutput[] { transactionOutput }; /** CREATE FAKE CURRENT TRANSACTION */ coinRef = new CoinReference { PrevHash = initialTransaction.Hash, PrevIndex = 0 }; currentTransaction.Inputs = new CoinReference[] { coinRef }; /**INIT CONTEXT*/ service.transactions[initialTransaction.Hash] = initialTransaction; service.transactions[currentTransaction.Hash] = currentTransaction; scriptContainer = initialTransaction; }
public static Transaction CreateGlobalTransfer(SignDelegate2 sign) { CoinReference[] inputs = new CoinReference[] { new CoinReference() { PrevHash = new UInt256(preTxId.Remove(0, 2).HexToBytes().Reverse().ToArray()), PrevIndex = prevIndex //vout n } }.ToArray(); var outputs = new List <TransactionOutput>(); var output1 = new TransactionOutput() { AssetId = UInt256.Parse(assetid), ScriptHash = tansferAddress.ToScriptHash(), Value = tansferValue }; outputs.Add(output1); var tx = new ContractTransaction() { Outputs = outputs.ToArray(), Inputs = inputs, Attributes = new TransactionAttribute[0], Witnesses = new Witness[0] }; return(sign.Invoke(tx)); }
// Create ClaimTransaction with 'countRefs' CoinReferences public static ClaimTransaction GetClaimTransaction(int countRefs) { CoinReference[] refs = new CoinReference[countRefs]; for (var i = 0; i < countRefs; i++) { refs[i] = GetCoinReference(new UInt256(Crypto.Default.Hash256(new BigInteger(i).ToByteArray()))); } //============================== //=== Generating random Hash === var randomBytes = new byte[20]; _random.NextBytes(randomBytes); //============================== return(new ClaimTransaction { Claims = refs, Attributes = new TransactionAttribute[] { new TransactionAttribute { Usage = TransactionAttributeUsage.Script, Data = randomBytes } }, Inputs = new CoinReference[0], Outputs = new TransactionOutput[0], Witnesses = new Witness[0] }); }
public static CoinReferenceContract FromDomain(CoinReference source) { return(new CoinReferenceContract { PrevHash = source.PrevHash.ToString(), PrevIndex = source.PrevIndex }); }
public static CoinReferenceWrapper Wrap(CoinReference reference) { return(new CoinReferenceWrapper { PrevHash = reference.PrevHash, PrevIndex = reference.PrevIndex }); }
private JObject ConvertTransactionInputs(CoinReference coinReference) { var json = new JObject(); json["txid"] = coinReference.PrevHash.ToString(); json["vout"] = coinReference.PrevIndex; return(json); }
public void Claims_Set() { CoinReference val = new CoinReference(); CoinReference[] refs = new CoinReference[] { val }; uut.Claims = refs; uut.Claims.Length.Should().Be(1); uut.Claims[0].Should().Be(val); }
public static IEnumerable <Coin> GetCoins(Snapshot snapshot, ImmutableHashSet <UInt160> addresses) { var coinIndex = new Dictionary <CoinReference, Coin>(); var height = snapshot.Height; for (uint blockIndex = 0; blockIndex < height; blockIndex++) { var block = snapshot.GetBlock(blockIndex); for (var txIndex = 0; txIndex < block.Transactions.Length; txIndex++) { var tx = block.Transactions[txIndex]; for (var outIndex = 0; outIndex < tx.Outputs.Length; outIndex++) { var output = tx.Outputs[outIndex]; if (addresses.Contains(output.ScriptHash)) { var coinRef = new CoinReference() { PrevHash = tx.Hash, PrevIndex = (ushort)outIndex }; coinIndex.Add(coinRef, new Coin() { Reference = coinRef, Output = output, State = CoinState.Confirmed }); } } for (var inIndex = 0; inIndex < tx.Inputs.Length; inIndex++) { if (coinIndex.TryGetValue(tx.Inputs[inIndex], out var coin)) { coin.State |= CoinState.Spent | CoinState.Confirmed; } } if (tx is ClaimTransaction claimTx) { for (var claimIndex = 0; claimIndex < claimTx.Claims.Length; claimIndex++) { if (coinIndex.TryGetValue(claimTx.Claims[claimIndex], out var coin)) { coin.State |= CoinState.Claimed; } } } } } return(coinIndex.Select(kvp => kvp.Value)); }
private static bool Input_GetIndex(ScriptEngine engine) { CoinReference input = engine.EvaluationStack.Pop().GetInterface <CoinReference>(); if (input == null) { return(false); } engine.EvaluationStack.Push((int)input.PrevIndex); return(true); }
private static bool Input_GetHash(ExecutionEngine engine) { CoinReference input = engine.EvaluationStack.Pop().GetInterface <CoinReference>(); if (input == null) { return(false); } engine.EvaluationStack.Push(input.PrevHash.ToArray()); return(true); }
protected virtual bool Input_GetIndex(ExecutionEngine engine) { CoinReference input = engine.EvaluationStack.Pop().GetInterface <CoinReference>(); if (input == null) { return(false); } engine.EvaluationStack.Push((int)input.PrevIndex); return(true); }
protected virtual bool Input_GetHash(ExecutionEngine engine) { CoinReference input = (engine.EvaluationStack.Pop() as VM.Types.InteropInterface).GetInterface <CoinReference>(); if (input == null) { return(false); } engine.EvaluationStack.Push(input.PrevHash.ToArray()); return(true); }
public async Task Persist_TransactionWithInputs_SpendOutputs() { var repositoryMock = AutoMockContainer.GetMock <IRepository>(); var input = new ContractTransaction { Hash = UInt256.Parse(RandomInt().ToString("X64")), Inputs = new CoinReference[3] }; var txs = new Transaction[3]; for (var i = 0; i < input.Inputs.Length; i++) { var reference = new CoinReference { PrevHash = UInt256.Parse(RandomInt().ToString("X64")), PrevIndex = 0 }; input.Inputs[i] = reference; txs[i] = new Transaction { Hash = reference.PrevHash, Outputs = new[] { new TransactionOutput { AssetId = UInt256.Parse(RandomInt().ToString("X64")), ScriptHash = UInt160.Parse(RandomInt().ToString("X40")), Value = new Fixed8(RandomInt()) } } }; repositoryMock .Setup(m => m.GetTransaction(reference.PrevHash)) .ReturnsAsync(txs[i]); repositoryMock .Setup(m => m.GetCoinStates(reference.PrevHash)) .ReturnsAsync(new[] { CoinState.Confirmed }); } var accountManagerMock = AutoMockContainer.GetMock <IAccountManager>(); var testee = AutoMockContainer.Create <TransactionPersister>(); await testee.Persist(input); for (var i = 0; i < input.Outputs.Length; i++) { var output = txs[i].Outputs[0]; accountManagerMock.Verify(m => m.UpdateBalance(output.ScriptHash, output.AssetId, -output.Value)); var hash = txs[i].Hash; repositoryMock.Verify(m => m.AddCoinStates(It.Is <UInt256>(u => u.Equals(hash)), It.Is <CoinState[]>(cs => cs.Length == 1 && cs[0].Equals(CoinState.Confirmed | CoinState.Spent)))); } }
public void Size__Get_0_Claims() { CoinReference[] refs = new CoinReference[0]; uut.Claims = refs; uut.Attributes = new TransactionAttribute[0]; uut.Inputs = new CoinReference[0]; uut.Outputs = new TransactionOutput[0]; uut.Scripts = new Witness[0]; uut.Size.Should().Be(7); // 1, 1, 1, 1, 1, 1 + claims 1 }
public void Equals_SameIndex() { UInt256 prevHashVal; ushort prevIndexVal; setupCoinReferenceWithVals(uut, out prevHashVal, out prevIndexVal); CoinReference newCoinRef = new CoinReference(); setupCoinReferenceWithVals(newCoinRef, out prevHashVal, out prevIndexVal); uut.Equals(newCoinRef).Should().BeTrue(); }
public void Equals_DiffIndex() { UInt256 prevHashVal; ushort prevIndexVal; setupCoinReferenceWithVals(uut, out prevHashVal, out prevIndexVal); CoinReference newCoinRef = new CoinReference(); setupCoinReferenceWithVals(newCoinRef, out prevHashVal, out prevIndexVal); newCoinRef.PrevIndex = 73; uut.Equals(newCoinRef).Should().BeFalse(); }
public void Equals_DiffHash() { UInt256 prevHashVal; ushort prevIndexVal; setupCoinReferenceWithVals(uut, out prevHashVal, out prevIndexVal); CoinReference newCoinRef = new CoinReference(); setupCoinReferenceWithVals(newCoinRef, out prevHashVal, out prevIndexVal); newCoinRef.PrevHash = new UInt256(TestUtils.GetByteArray(32, 0x78)); uut.Equals(newCoinRef).Should().BeFalse(); }
private bool Input_GetHash(ExecutionEngine engine) { if (engine.CurrentContext.EvaluationStack.Pop() is InteropContract _interface) { CoinReference input = _interface.GetInterface <CoinReference>(); if (input == null) { return(false); } engine.CurrentContext.EvaluationStack.Push(input.PrevHash.ToArray()); return(true); } return(false); }
private bool Input_GetIndex(ExecutionEngine engine) { if (engine.CurrentContext.EvaluationStack.Pop() is InteropInterface _interface) { CoinReference input = _interface.GetInterface <CoinReference>(); if (input == null) { return(false); } engine.CurrentContext.EvaluationStack.Push((int)input.PrevIndex); return(true); } return(false); }
// Create ClaimTransaction with 'countRefs' CoinReferences public static ClaimTransaction GetClaimTransaction(int countRefs) { CoinReference[] refs = new CoinReference[countRefs]; for (var i = 0; i < countRefs; i++) { refs[i] = GetCoinReference(new UInt256(Crypto.Default.Hash256(new BigInteger(i).ToByteArray()))); } return(new ClaimTransaction { Claims = refs, Attributes = new TransactionAttribute[0], Inputs = new CoinReference[0], Outputs = new TransactionOutput[0], Witnesses = new Witness[0] }); }
private IssueTransaction getIssueTransaction(bool inputVal, decimal outputVal, UInt256 assetId) { setupTestBlockchain(assetId); CoinReference[] inputsVal; if (inputVal) { inputsVal = new[] { new CoinReference { PrevHash = UInt256.Zero, PrevIndex = 0 } }; } else { inputsVal = new CoinReference[0]; } return(new IssueTransaction { Attributes = new TransactionAttribute[0], Inputs = inputsVal, Outputs = new[] { new TransactionOutput { AssetId = assetId, Value = Fixed8.FromDecimal(outputVal), ScriptHash = Contract.CreateMultiSigRedeemScript(1, TestUtils.StandbyValidators).ToScriptHash() } }, Scripts = new[] { new Witness { InvocationScript = new byte[0], VerificationScript = new[] { (byte)OpCode.PUSHT } } } }); }
public static void InitTransactionContext(string scriptHash, int value, ushort inputAmount = 1) { Transaction initialTransaction = new CustomTransaction(TransactionType.ContractTransaction); Transaction currentTransaction = new CustomTransaction(TransactionType.ContractTransaction); initialTransaction.Outputs = new TransactionOutput[inputAmount]; currentTransaction.Inputs = new CoinReference[inputAmount]; for (ushort i = 0; i < inputAmount; ++i) { /** CREATE FAKE PREVIOUS TRANSACTION */ var transactionOutput = new TransactionOutput { ScriptHash = UInt160.Parse(scriptHash), Value = new Fixed8(value), AssetId = UInt256.Parse(NEO_ASSET_ID) }; initialTransaction.Outputs[i] = transactionOutput; /** CREATE FAKE CURRENT TRANSACTION */ var coinRef = new CoinReference { PrevHash = initialTransaction.Hash, PrevIndex = i }; currentTransaction.Outputs = new TransactionOutput[1]; currentTransaction.Outputs[0] = new TransactionOutput { ScriptHash = UInt160.Parse(scriptHash), Value = new Fixed8(value), AssetId = UInt256.Parse(NEO_ASSET_ID) }; currentTransaction.Inputs[i] = coinRef; } /**INIT CONTEXT*/ service.transactions[initialTransaction.Hash] = initialTransaction; scriptContainer = currentTransaction; }
public static Transaction Claim(Wallet wallet) { CoinReference[] claims = wallet.GetUnclaimedCoins().Select(p => p.Reference).ToArray(); if (claims.Length == 0) { return(null); } ClaimTransaction tx = new ClaimTransaction { Claims = claims, Attributes = new TransactionAttribute[0], Inputs = new CoinReference[0], Outputs = new[] { new TransactionOutput { AssetId = Blockchain.UtilityToken.Hash, Value = Blockchain.CalculateBonus(claims), ScriptHash = wallet.GetChangeAddress() } } }; //交易输入是 1 GAS var input = new CoinReference() { PrevHash = new UInt256("0x51ac4f7f1662d8c9379ccce3fa7cd2085b9a865edfa53ad892352a41768dd1de".Remove(0, 2).HexToBytes().Reverse().ToArray()), PrevIndex = 0 }; //交易输出是 0.999 GAS,找回到原地址 var output = new TransactionOutput() { AssetId = Blockchain.UtilityToken.Hash, //Asset Id, this is NEO ScriptHash = Wallet.ToScriptHash("AJd31a8rYPEBkY1QSxpsGy8mdU4vTYTD4U"), //Receiver Value = new Fixed8((long)(0.999 * (long)Math.Pow(10, 8))) //Value (satoshi unit) }; //则手续费是 0.001 GAS tx.Inputs.ToList().Add(input); tx.Outputs.ToList().Add(output); return(tx); }
private ContractTransaction getContractTransaction(bool inputVal, decimal outputVal, UInt256 assetId) { CoinReference[] inputsVal; if (inputVal) { inputsVal = new[] { TestUtils.GetCoinReference(null) }; } else { inputsVal = new CoinReference[0]; } return(new ContractTransaction { Attributes = new TransactionAttribute[0], Inputs = inputsVal, Outputs = new[] { new TransactionOutput { AssetId = assetId, Value = Fixed8.FromDecimal(outputVal), ScriptHash = Contract.CreateMultiSigRedeemScript(1, TestUtils.StandbyValidators).ToScriptHash() } }, Witnesses = new[] { new Witness { InvocationScript = new byte[0], VerificationScript = new[] { (byte)OpCode.PUSHT } } } }); }
private void ProcessNewBlock(Block block) { Coin[] changeset; lock (contracts) lock (coins) { foreach (Transaction tx in block.Transactions) { for (ushort index = 0; index < tx.Outputs.Length; index++) { TransactionOutput output = tx.Outputs[index]; AddressState state = CheckAddressState(output.ScriptHash); if (state.HasFlag(AddressState.InWallet)) { CoinReference key = new CoinReference { PrevHash = tx.Hash, PrevIndex = index }; if (coins.Contains(key)) { coins[key].State |= CoinState.Confirmed; } else { coins.Add(new Coin { Reference = key, Output = output, State = CoinState.Confirmed }); } if (state.HasFlag(AddressState.WatchOnly)) { coins[key].State |= CoinState.WatchOnly; } } } } foreach (Transaction tx in block.Transactions) { foreach (CoinReference input in tx.Inputs) { if (coins.Contains(input)) { if (coins[input].Output.AssetId.Equals(Blockchain.SystemShare.Hash)) { coins[input].State |= CoinState.Spent | CoinState.Confirmed; } else { coins.Remove(input); } } } } foreach (ClaimTransaction tx in block.Transactions.OfType <ClaimTransaction>()) { foreach (CoinReference claim in tx.Claims) { if (coins.Contains(claim)) { coins.Remove(claim); } } } current_height++; changeset = coins.GetChangeSet(); OnProcessNewBlock(block, changeset.Where(p => ((ITrackable <CoinReference>)p).TrackState == TrackState.Added), changeset.Where(p => ((ITrackable <CoinReference>)p).TrackState == TrackState.Changed), changeset.Where(p => ((ITrackable <CoinReference>)p).TrackState == TrackState.Deleted)); coins.Commit(); } if (changeset.Length > 0) { BalanceChanged?.Invoke(this, EventArgs.Empty); } }
private void ProcessBlock(Block block, HashSet <UInt160> accounts, WriteBatch batch) { foreach (Transaction tx in block.Transactions) { HashSet <UInt160> accounts_changed = new HashSet <UInt160>(); for (ushort index = 0; index < tx.Outputs.Length; index++) { TransactionOutput output = tx.Outputs[index]; if (accounts_tracked.ContainsKey(output.ScriptHash)) { CoinReference reference = new CoinReference { PrevHash = tx.Hash, PrevIndex = index }; if (coins_tracked.TryGetValue(reference, out Coin coin)) { coin.State |= CoinState.Confirmed; } else { accounts_tracked[output.ScriptHash].Add(reference); coins_tracked.Add(reference, coin = new Coin { Reference = reference, Output = output, State = CoinState.Confirmed }); } batch.Put(SliceBuilder.Begin(DataEntryPrefix.ST_Coin).Add(reference), SliceBuilder.Begin().Add(output).Add((byte)coin.State)); accounts_changed.Add(output.ScriptHash); } } foreach (CoinReference input in tx.Inputs) { if (coins_tracked.TryGetValue(input, out Coin coin)) { if (coin.Output.AssetId.Equals(Blockchain.GoverningToken.Hash)) { coin.State |= CoinState.Spent | CoinState.Confirmed; batch.Put(SliceBuilder.Begin(DataEntryPrefix.ST_Coin).Add(input), SliceBuilder.Begin().Add(coin.Output).Add((byte)coin.State)); } else { accounts_tracked[coin.Output.ScriptHash].Remove(input); coins_tracked.Remove(input); batch.Delete(DataEntryPrefix.ST_Coin, input); } accounts_changed.Add(coin.Output.ScriptHash); } } switch (tx) { case MinerTransaction _: case ContractTransaction _: #pragma warning disable CS0612 case PublishTransaction _: #pragma warning restore CS0612 break; case ClaimTransaction tx_claim: foreach (CoinReference claim in tx_claim.Claims) { if (coins_tracked.TryGetValue(claim, out Coin coin)) { accounts_tracked[coin.Output.ScriptHash].Remove(claim); coins_tracked.Remove(claim); batch.Delete(DataEntryPrefix.ST_Coin, claim); accounts_changed.Add(coin.Output.ScriptHash); } } break; #pragma warning disable CS0612 case EnrollmentTransaction tx_enrollment: if (accounts_tracked.ContainsKey(tx_enrollment.ScriptHash)) { accounts_changed.Add(tx_enrollment.ScriptHash); } break; case RegisterTransaction tx_register: if (accounts_tracked.ContainsKey(tx_register.OwnerScriptHash)) { accounts_changed.Add(tx_register.OwnerScriptHash); } break; #pragma warning restore CS0612 default: foreach (UInt160 hash in tx.Witnesses.Select(p => p.ScriptHash)) { if (accounts_tracked.ContainsKey(hash)) { accounts_changed.Add(hash); } } break; } if (accounts_changed.Count > 0) { foreach (UInt160 account in accounts_changed) { batch.Put(SliceBuilder.Begin(DataEntryPrefix.ST_Transaction).Add(account).Add(tx.Hash), false); } WalletTransaction?.Invoke(null, new WalletTransactionEventArgs { Transaction = tx, RelatedAccounts = accounts_changed.ToArray(), Height = block.Index, Time = block.Timestamp }); } } }
private static void ProcessBlock(Block block, HashSet <UInt160> accounts, WriteBatch batch) { foreach (Transaction tx in block.Transactions) { HashSet <UInt160> accounts_changed = new HashSet <UInt160>(); for (ushort index = 0; index < tx.Outputs.Length; index++) { TransactionOutput output = tx.Outputs[index]; if (accounts_tracked.ContainsKey(output.ScriptHash)) { CoinReference reference = new CoinReference { PrevHash = tx.Hash, PrevIndex = index }; if (coins_tracked.TryGetValue(reference, out Coin coin)) { coin.State |= CoinState.Confirmed; } else { accounts_tracked[output.ScriptHash].Add(reference); coins_tracked.Add(reference, coin = new Coin { Reference = reference, Output = output, State = CoinState.Confirmed }); } batch.Put(SliceBuilder.Begin(DataEntryPrefix.ST_Coin).Add(reference), SliceBuilder.Begin().Add(output).Add((byte)coin.State)); accounts_changed.Add(output.ScriptHash); } } foreach (CoinReference input in tx.Inputs) { if (coins_tracked.TryGetValue(input, out Coin coin)) { if (coin.Output.AssetId.Equals(Blockchain.GoverningToken.Hash)) { coin.State |= CoinState.Spent | CoinState.Confirmed; batch.Put(SliceBuilder.Begin(DataEntryPrefix.ST_Coin).Add(input), SliceBuilder.Begin().Add(coin.Output).Add((byte)coin.State)); } else { accounts_tracked[coin.Output.ScriptHash].Remove(input); coins_tracked.Remove(input); batch.Delete(DataEntryPrefix.ST_Coin, input); } accounts_changed.Add(coin.Output.ScriptHash); } } if (tx is ClaimTransaction ctx) { foreach (CoinReference claim in ctx.Claims) { if (coins_tracked.TryGetValue(claim, out Coin coin)) { accounts_tracked[coin.Output.ScriptHash].Remove(claim); coins_tracked.Remove(claim); batch.Delete(DataEntryPrefix.ST_Coin, claim); accounts_changed.Add(coin.Output.ScriptHash); } } } if (accounts_changed.Count > 0) { foreach (UInt160 account in accounts_changed) { batch.Put(SliceBuilder.Begin(DataEntryPrefix.ST_Transaction).Add(account).Add(tx.Hash), false); } BalanceChanged?.Invoke(null, new BalanceEventArgs { Transaction = tx, RelatedAccounts = accounts_changed.ToArray(), Height = block.Index, Time = block.Timestamp }); } } }
public void TestSetup() { uut = new CoinReference(); }