public static bool TryLoad(ProtocolSettings settings, DataCache snapshot, UInt160 scriptHash, out Nep17Contract contract)
        {
            if (scriptHash == NativeContract.NEO.Hash)
            {
                contract = Nep17Contract.Create(NativeContract.NEO);
                return(true);
            }

            if (scriptHash == NativeContract.GAS.Hash)
            {
                contract = Nep17Contract.Create(NativeContract.GAS);
                return(true);
            }

            var contractState = NativeContract.ContractManagement.GetContract(snapshot, scriptHash);

            if (contractState != null)
            {
                using var sb = new ScriptBuilder();
                sb.EmitDynamicCall(scriptHash, "symbol");
                sb.EmitDynamicCall(scriptHash, "decimals");

                using var engine = sb.Invoke(settings, snapshot);
                if (engine.State != VMState.FAULT && engine.ResultStack.Count >= 2)
                {
                    var decimals = (byte)engine.ResultStack.Pop <Neo.VM.Types.Integer>().GetInteger();
                    var symbol   = Encoding.UTF8.GetString(engine.ResultStack.Pop().GetSpan());
                    contract = new Nep17Contract(symbol, decimals, scriptHash);
                    return(true);
                }
            }

            contract = default;
            return(false);
        }
Beispiel #2
0
        public AssetDescriptor(UInt160 asset_id)
        {
            using SnapshotView snapshot = Blockchain.Singleton.GetSnapshot();
            var contract = NativeContract.ContractManagement.GetContract(snapshot, asset_id);

            if (contract is null)
            {
                throw new ArgumentException();
            }

            byte[] script;
            using (ScriptBuilder sb = new ScriptBuilder())
            {
                sb.EmitDynamicCall(asset_id, "decimals", true);
                sb.EmitDynamicCall(asset_id, "symbol", true);
                script = sb.ToArray();
            }
            using ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, gas: 0_10000000);
            if (engine.State.HasFlag(VMState.FAULT))
            {
                throw new ArgumentException();
            }
            this.AssetId   = asset_id;
            this.AssetName = contract.Manifest.Name;
            this.Symbol    = engine.ResultStack.Pop().GetString();
            this.Decimals  = (byte)engine.ResultStack.Pop().GetInteger();
        }
Beispiel #3
0
        public AssetDescriptor(DataCache snapshot, ProtocolSettings settings, UInt160 asset_id)
        {
            var contract = NativeContract.ContractManagement.GetContract(snapshot, asset_id);

            if (contract is null)
            {
                throw new ArgumentException(null, nameof(asset_id));
            }

            byte[] script;
            using (ScriptBuilder sb = new ScriptBuilder())
            {
                sb.EmitDynamicCall(asset_id, "decimals", CallFlags.ReadOnly);
                sb.EmitDynamicCall(asset_id, "symbol", CallFlags.ReadOnly);
                script = sb.ToArray();
            }
            using ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, settings: settings, gas: 0_10000000);
            if (engine.State != VMState.HALT)
            {
                throw new ArgumentException(null, nameof(asset_id));
            }
            this.AssetId   = asset_id;
            this.AssetName = contract.Manifest.Name;
            this.Symbol    = engine.ResultStack.Pop().GetString();
            this.Decimals  = (byte)engine.ResultStack.Pop().GetInteger();
        }
Beispiel #4
0
        public void Json_Serialize()
        {
            var snapshot = TestBlockchain.GetTestSnapshot();

            // Good

            using (var script = new ScriptBuilder())
            {
                script.EmitDynamicCall(NativeContract.StdLib.Hash, "jsonSerialize", 5);
                script.EmitDynamicCall(NativeContract.StdLib.Hash, "jsonSerialize", true);
                script.EmitDynamicCall(NativeContract.StdLib.Hash, "jsonSerialize", "test");
                script.EmitDynamicCall(NativeContract.StdLib.Hash, "jsonSerialize", new object[] { null });
                script.EmitDynamicCall(NativeContract.StdLib.Hash, "jsonSerialize", new ContractParameter(ContractParameterType.Map)
                {
                    Value = new List <KeyValuePair <ContractParameter, ContractParameter> >()
                    {
                        { new KeyValuePair <ContractParameter, ContractParameter>(
                              new ContractParameter(ContractParameterType.String)
                            {
                                Value = "key"
                            },
                              new ContractParameter(ContractParameterType.String)
                            {
                                Value = "value"
                            }) }
                    }
                });

                using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings))
                {
                    engine.LoadScript(script.ToArray());

                    Assert.AreEqual(engine.Execute(), VMState.HALT);
                    Assert.AreEqual(5, engine.ResultStack.Count);

                    Assert.IsTrue(engine.ResultStack.Pop <ByteString>().GetString() == "{\"key\":\"value\"}");
                    Assert.IsTrue(engine.ResultStack.Pop <ByteString>().GetString() == "null");
                    Assert.IsTrue(engine.ResultStack.Pop <ByteString>().GetString() == "\"test\"");
                    Assert.IsTrue(engine.ResultStack.Pop <ByteString>().GetString() == "1");
                    Assert.IsTrue(engine.ResultStack.Pop <ByteString>().GetString() == "5");
                }
            }

            // Error

            using (var script = new ScriptBuilder())
            {
                script.EmitDynamicCall(NativeContract.StdLib.Hash, "jsonSerialize");

                using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings))
                {
                    engine.LoadScript(script.ToArray());

                    Assert.AreEqual(engine.Execute(), VMState.FAULT);
                    Assert.AreEqual(0, engine.ResultStack.Count);
                }
            }
        }
Beispiel #5
0
        public void Json_Deserialize()
        {
            var snapshot = TestBlockchain.GetTestSnapshot();

            // Good

            using (var script = new ScriptBuilder())
            {
                script.EmitDynamicCall(NativeContract.StdLib.Hash, "jsonDeserialize", "123");
                script.EmitDynamicCall(NativeContract.StdLib.Hash, "jsonDeserialize", "null");

                using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings))
                {
                    engine.LoadScript(script.ToArray());

                    Assert.AreEqual(engine.Execute(), VMState.HALT);
                    Assert.AreEqual(2, engine.ResultStack.Count);

                    engine.ResultStack.Pop <Null>();
                    Assert.IsTrue(engine.ResultStack.Pop().GetInteger() == 123);
                }
            }

            // Error 1 - Wrong Json

            using (var script = new ScriptBuilder())
            {
                script.EmitDynamicCall(NativeContract.StdLib.Hash, "jsonDeserialize", "***");

                using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings))
                {
                    engine.LoadScript(script.ToArray());

                    Assert.AreEqual(engine.Execute(), VMState.FAULT);
                    Assert.AreEqual(0, engine.ResultStack.Count);
                }
            }

            // Error 2 - No decimals

            using (var script = new ScriptBuilder())
            {
                script.EmitDynamicCall(NativeContract.StdLib.Hash, "jsonDeserialize", "123.45");

                using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings))
                {
                    engine.LoadScript(script.ToArray());

                    Assert.AreEqual(engine.Execute(), VMState.FAULT);
                    Assert.AreEqual(0, engine.ResultStack.Count);
                }
            }
        }
Beispiel #6
0
        public JObject GetNep17Balances(JArray _params)
        {
            UInt160 userScriptHash = GetScriptHashFromParam(_params[0].AsString());

            JObject json     = new();
            JArray  balances = new();

            json["address"] = userScriptHash.ToAddress(_neoSystem.Settings.AddressVersion);
            json["balance"] = balances;

            int count = 0;

            byte[] prefix = Key(Nep17BalancePrefix, userScriptHash);
            foreach (var(key, value) in _db.FindPrefix <Nep17BalanceKey, TokenBalance>(prefix))
            {
                if (NativeContract.ContractManagement.GetContract(_neoSystem.StoreView, key.AssetScriptHash) is null)
                {
                    continue;
                }

                try
                {
                    using var script = new ScriptBuilder();
                    script.EmitDynamicCall(key.AssetScriptHash, "decimals");
                    script.EmitDynamicCall(key.AssetScriptHash, "symbol");

                    var engine   = ApplicationEngine.Run(script.ToArray(), _neoSystem.StoreView, settings: _neoSystem.Settings);
                    var symbol   = engine.ResultStack.Pop().GetString();
                    var decimals = engine.ResultStack.Pop().GetInteger();
                    var name     = NativeContract.ContractManagement.GetContract(_neoSystem.StoreView, key.AssetScriptHash).Manifest.Name;

                    balances.Add(new JObject
                    {
                        ["assethash"]        = key.AssetScriptHash.ToString(),
                        ["name"]             = name,
                        ["symbol"]           = symbol,
                        ["decimals"]         = decimals.ToString(),
                        ["amount"]           = value.Balance.ToString(),
                        ["lastupdatedblock"] = value.LastUpdatedBlock
                    });
                    count++;
                    if (count >= _maxResults)
                    {
                        break;
                    }
                }
                catch { }
            }
            return(json);
        }
Beispiel #7
0
        public async Task <Script> BuildInvocationScriptAsync(string contract, string operation, IReadOnlyList <string>?arguments = null)
        {
            if (string.IsNullOrEmpty(operation))
            {
                throw new InvalidOperationException($"invalid contract operation \"{operation}\"");
            }

            var parser = await expressNode.GetContractParameterParserAsync(chainManager.Chain).ConfigureAwait(false);

            var scriptHash = parser.TryLoadScriptHash(contract, out var value)
                ? value
                : UInt160.TryParse(contract, out var uint160)
                    ? uint160
                    : throw new InvalidOperationException($"contract \"{contract}\" not found");

            arguments ??= Array.Empty <string>();
            var @params = new ContractParameter[arguments.Count];

            for (int i = 0; i < arguments.Count; i++)
            {
                @params[i] = ConvertArg(arguments[i], parser);
            }

            using var scriptBuilder = new ScriptBuilder();
            scriptBuilder.EmitDynamicCall(scriptHash, operation, @params);
            return(scriptBuilder.ToArray());
Beispiel #8
0
        public void TestExecutionEngine_GetCallingScriptHash()
        {
            // Test without

            var engine = GetEngine(true);

            engine.CallingScriptHash.Should().BeNull();

            // Test real

            using ScriptBuilder scriptA = new ScriptBuilder();
            scriptA.Emit(OpCode.DROP); // Drop arguments
            scriptA.Emit(OpCode.DROP); // Drop method
            scriptA.EmitSysCall(ApplicationEngine.System_Runtime_GetCallingScriptHash);

            var contract = new ContractState()
            {
                Manifest = TestUtils.CreateManifest("test", ContractParameterType.Any, ContractParameterType.Integer, ContractParameterType.Integer),
                Nef      = new NefFile {
                    Script = scriptA.ToArray()
                },
                Hash = scriptA.ToArray().ToScriptHash()
            };

            engine = GetEngine(true, true, false);
            engine.Snapshot.AddContract(contract.Hash, contract);

            using ScriptBuilder scriptB = new ScriptBuilder();
            scriptB.EmitDynamicCall(contract.Hash, "test", true, 0, 1);
            engine.LoadScript(scriptB.ToArray());

            Assert.AreEqual(VMState.HALT, engine.Execute());

            engine.ResultStack.Pop().GetSpan().ToHexString().Should().Be(scriptB.ToArray().ToScriptHash().ToArray().ToHexString());
        }
Beispiel #9
0
        public static void DestroyContract(this StoreView snapshot, UInt160 callingScriptHash)
        {
            var script = new ScriptBuilder();

            script.EmitDynamicCall(NativeContract.ContractManagement.Hash, "destroy");

            var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot);

            engine.LoadScript(script.ToArray());

            // Fake calling script hash
            if (callingScriptHash != null)
            {
                engine.CurrentContext.GetState <ExecutionContextState>().CallingScriptHash = callingScriptHash;
                engine.CurrentContext.GetState <ExecutionContextState>().ScriptHash        = callingScriptHash;
            }

            if (engine.Execute() != VMState.HALT)
            {
                Exception exception = engine.FaultException;
                while (exception?.InnerException != null)
                {
                    exception = exception.InnerException;
                }
                throw exception ?? new InvalidOperationException();
            }
        }
Beispiel #10
0
        private void OnUnregisterCandidateCommand(UInt160 account)
        {
            if (NoWallet())
            {
                return;
            }
            WalletAccount currentAccount = CurrentWallet.GetAccount(account);

            if (currentAccount == null)
            {
                ConsoleHelper.Warning("This address isn't in your wallet!");
                return;
            }
            else
            {
                if (currentAccount.Lock || currentAccount.WatchOnly)
                {
                    ConsoleHelper.Warning("Locked or WatchOnly address.");
                    return;
                }
            }

            ECPoint publicKey = currentAccount?.GetKey()?.PublicKey;

            byte[] script;
            using (ScriptBuilder scriptBuilder = new ScriptBuilder())
            {
                scriptBuilder.EmitDynamicCall(NativeContract.NEO.Hash, "unregisterCandidate", publicKey);
                script = scriptBuilder.ToArray();
            }

            SendTransaction(script, account);
        }
Beispiel #11
0
        public async Task <object> SetStoragePrice(uint factor, List <UInt160> signers = null)
        {
            if (factor == 0 || factor > PolicyContract.MaxStoragePrice)
            {
                return(Error(ErrorCode.InvalidPara, $"input value should between 0 and  10000000"));
            }
            if (CurrentWallet == null)
            {
                return(Error(ErrorCode.WalletNotOpen));
            }
            using ScriptBuilder sb = new ScriptBuilder();
            sb.EmitDynamicCall(NativeContract.Policy.Hash, "setStoragePrice", new ContractParameter
            {
                Type  = ContractParameterType.Integer,
                Value = factor
            });
            if (signers == null)
            {
                signers = new List <UInt160>();
            }
            var committee = NativeContract.NEO.GetCommitteeAddress(Helpers.GetDefaultSnapshot());

            signers.Add(committee);
            return(await SignAndBroadcastTx(sb.ToArray(), signers.ToArray()));
        }
Beispiel #12
0
        private void OnRegisterCandidateCommand(UInt160 account)
        {
            var testGas = NativeContract.NEO.GetRegisterPrice(NeoSystem.StoreView) + (BigInteger)Math.Pow(10, NativeContract.GAS.Decimals) * 10;

            if (NoWallet())
            {
                return;
            }
            WalletAccount currentAccount = CurrentWallet.GetAccount(account);

            if (currentAccount == null)
            {
                ConsoleHelper.Warning("This address isn't in your wallet!");
                return;
            }
            else
            {
                if (currentAccount.Lock || currentAccount.WatchOnly)
                {
                    ConsoleHelper.Warning("Locked or WatchOnly address.");
                    return;
                }
            }

            ECPoint publicKey = currentAccount.GetKey()?.PublicKey;

            byte[] script;
            using (ScriptBuilder scriptBuilder = new ScriptBuilder())
            {
                scriptBuilder.EmitDynamicCall(NativeContract.NEO.Hash, "registerCandidate", publicKey);
                script = scriptBuilder.ToArray();
            }

            SendTransaction(script, account, (long)testGas);
        }
Beispiel #13
0
        /// <summary>
        /// apply for new validator
        /// </summary>
        /// <param name="pubkey"></param>
        /// <returns></returns>
        public async Task <object> ApplyForValidator(string pubkey)
        {
            if (CurrentWallet == null)
            {
                return(Error(ErrorCode.WalletNotOpen));
            }
            if (pubkey.IsNull())
            {
                return(Error(ErrorCode.ParameterIsNull));
            }
            ECPoint publicKey = null;

            try
            {
                publicKey = ECPoint.Parse(pubkey, ECCurve.Secp256r1);
            }
            catch (Exception e)
            {
                return(Error(ErrorCode.InvalidPara));
            }
            var snapshot   = Helpers.GetDefaultSnapshot();
            var candidates = NativeContract.NEO.GetCandidates(snapshot);

            if (candidates.Any(v => v.PublicKey.Equals(publicKey)))
            {
                return(Error(ErrorCode.ValidatorAlreadyExist));
            }

            var contract = Contract.CreateSignatureContract(publicKey);
            var account  = contract.ScriptHash;

            using ScriptBuilder sb = new ScriptBuilder();
            sb.EmitDynamicCall(NativeContract.NEO.Hash, "registerCandidate", publicKey);
            return(await SignAndBroadcastTxWithSender(sb.ToArray(), account, account));
        }
Beispiel #14
0
        public void TestInvoke()
        {
            var snapshot = TestBlockchain.GetTestSnapshot();

            snapshot.Add(NativeContract.ContractManagement.CreateStorageKey(8, testNativeContract.Hash), new StorageItem(new ContractState
            {
                Id       = 0,
                Nef      = testNativeContract.Nef,
                Hash     = testNativeContract.Hash,
                Manifest = testNativeContract.Manifest
            }));

            using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.OnPersist, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings, gas: 20_00000000))
            {
                using ScriptBuilder script = new ScriptBuilder();
                script.EmitDynamicCall(testNativeContract.Hash, "wrongMethod");
                engine.LoadScript(script.ToArray());
                engine.Execute().Should().Be(VMState.FAULT);
            }

            using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.OnPersist, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings, gas: 20_00000000))
            {
                using ScriptBuilder script = new ScriptBuilder();
                script.EmitDynamicCall(testNativeContract.Hash, "helloWorld");
                engine.LoadScript(script.ToArray());
                engine.Execute().Should().Be(VMState.HALT);
            }
        }
Beispiel #15
0
        public async Task TestDeployContract()
        {
            byte[] script;
            var    manifest = new ContractManifest()
            {
                Permissions = new[] { ContractPermission.DefaultPermission },
                Abi         = new ContractAbi()
                {
                    Events  = new ContractEventDescriptor[0],
                    Methods = new ContractMethodDescriptor[0]
                },
                Groups             = new ContractGroup[0],
                Trusts             = WildcardContainer <ContractPermissionDescriptor> .Create(),
                SupportedStandards = new string[]
                {
                    "NEP-10"
                },
                Extra = null,
            };

            using (ScriptBuilder sb = new ScriptBuilder())
            {
                sb.EmitDynamicCall(NativeContract.ContractManagement.Hash, "deploy", new byte[1], manifest.ToJson().ToString());
                script = sb.ToArray();
            }

            UT_TransactionManager.MockInvokeScript(rpcClientMock, script, new ContractParameter());

            ContractClient contractClient = new ContractClient(rpcClientMock.Object);
            var            result         = await contractClient.CreateDeployContractTxAsync(new byte[1], manifest, keyPair1);

            Assert.IsNotNull(result);
        }
Beispiel #16
0
        public static void UpdateContract(this DataCache snapshot, UInt160 callingScriptHash, byte[] nefFile, byte[] manifest)
        {
            var script = new ScriptBuilder();

            script.EmitDynamicCall(NativeContract.ContractManagement.Hash, "update", nefFile, manifest, null);

            var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings);

            engine.LoadScript(script.ToArray());

            // Fake calling script hash
            if (callingScriptHash != null)
            {
                engine.CurrentContext.GetState <ExecutionContextState>().NativeCallingScriptHash = callingScriptHash;
                engine.CurrentContext.GetState <ExecutionContextState>().ScriptHash = callingScriptHash;
            }

            if (engine.Execute() != VMState.HALT)
            {
                Exception exception = engine.FaultException;
                while (exception?.InnerException != null)
                {
                    exception = exception.InnerException;
                }
                throw exception ?? new InvalidOperationException();
            }
        }
Beispiel #17
0
        internal static bool Check_Register(DataCache snapshot, string name, UInt160 owner, Block persistingBlock)
        {
            using var engine = ApplicationEngine.Create(TriggerType.Application, new Nep17NativeContractExtensions.ManualWitness(owner), snapshot, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings);
            using var script = new ScriptBuilder();
            script.EmitDynamicCall(NativeContract.NameService.Hash, "register", new ContractParameter[] {
                new ContractParameter(ContractParameterType.String)
                {
                    Value = name
                },
                new ContractParameter(ContractParameterType.Hash160)
                {
                    Value = owner
                }
            });
            engine.LoadScript(script.ToArray());

            if (engine.Execute() == VMState.FAULT)
            {
                return(false);
            }

            var result = engine.ResultStack.Pop();

            Assert.IsInstanceOfType(result, typeof(VM.Types.Boolean));

            return(result.GetBoolean());
        }
Beispiel #18
0
        internal static bool Check_SetRecord(DataCache snapshot, string name, RecordType type, string data, UInt160 signedBy, Block persistingBlock)
        {
            using var engine = ApplicationEngine.Create(TriggerType.Application, new Nep17NativeContractExtensions.ManualWitness(signedBy), snapshot, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings);
            using var script = new ScriptBuilder();
            script.EmitDynamicCall(NativeContract.NameService.Hash, "setRecord", new ContractParameter[] {
                new ContractParameter(ContractParameterType.String)
                {
                    Value = name
                },
                new ContractParameter(ContractParameterType.Integer)
                {
                    Value = (int)type
                },
                new ContractParameter(ContractParameterType.String)
                {
                    Value = data
                }
            });
            engine.LoadScript(script.ToArray());

            if (engine.Execute() == VMState.FAULT)
            {
                return(false);
            }

            return(true);
        }
Beispiel #19
0
        /// <summary>
        /// query balance
        /// </summary>
        /// <param name="addresses"></param>
        /// <param name="assetId"></param>
        /// <param name="snapshot"></param>
        /// <returns></returns>
        public static List<BigDecimal> GetBalanceOf(this IEnumerable<UInt160> addresses, UInt160 assetId, DataCache snapshot)
        {
            var assetInfo = AssetCache.GetAssetInfo(assetId, snapshot);
            if (assetInfo == null)
            {
                throw new ArgumentException($"invalid assetId:[{assetId}]");
            }

            if (assetInfo.Asset == NativeContract.NEO.Hash)
            {
                return GetNativeBalanceOf(addresses, NativeContract.NEO, snapshot);
            }
            if (assetInfo.Asset == NativeContract.GAS.Hash)
            {
                return GetNativeBalanceOf(addresses, NativeContract.GAS, snapshot);
            }
            using var sb = new ScriptBuilder();
            foreach (var address in addresses)
            {
                sb.EmitDynamicCall(assetId, "balanceOf", address);
            }

            using ApplicationEngine engine = sb.ToArray().RunTestMode(snapshot);
            if (engine.State.HasFlag(VMState.FAULT))
            {
                throw new Exception($"query balance error");
            }

            var result = engine.ResultStack.Select(p => p.GetInteger());
            return result.Select(bigInt => new BigDecimal(bigInt, assetInfo.Decimals)).ToList();
        }
Beispiel #20
0
        public static ContractState DeployContract(this StoreView snapshot, UInt160 sender, byte[] nefFile, byte[] manifest, long gas = 200_00000000)
        {
            var script = new ScriptBuilder();

            script.EmitDynamicCall(NativeContract.ContractManagement.Hash, "deploy", nefFile, manifest);

            var engine = ApplicationEngine.Create(TriggerType.Application,
                                                  sender != null ? new Transaction()
            {
                Signers = new Signer[] { new Signer()
                                         {
                                             Account = sender
                                         } }
            } : null, snapshot, null, gas);

            engine.LoadScript(script.ToArray());

            if (engine.Execute() != VMState.HALT)
            {
                Exception exception = engine.FaultException;
                while (exception?.InnerException != null)
                {
                    exception = exception.InnerException;
                }
                throw exception ?? new InvalidOperationException();
            }

            var ret = new ContractState();

            ((IInteroperable)ret).FromStackItem(engine.ResultStack.Pop());
            return(ret);
        }
Beispiel #21
0
 public ApplicationEngine TestCall(string operation, params object[] args)
 {
     using (ScriptBuilder sb = new ScriptBuilder())
     {
         sb.EmitDynamicCall(Hash, operation, args);
         return(ApplicationEngine.Run(sb.ToArray()));
     }
 }
Beispiel #22
0
        /// <summary>
        /// read nep5 from chain, and set cache
        /// https://github.com/neo-project/proposals/blob/master/nep-5.mediawiki
        /// </summary>
        /// <param name="assetId"></param>
        /// <param name="snapshot"></param>
        /// <returns></returns>
        public static AssetInfo GetAssetInfoFromChain(UInt160 assetId, DataCache snapshot)
        {
            using var sb = new ScriptBuilder();
            sb.EmitDynamicCall(assetId, "decimals");
            sb.EmitDynamicCall(assetId, "symbol");
            //sb.EmitAppCall(assetId, "name");
            var contract = snapshot.GetContract(assetId);

            if (contract == null)
            {
                return(null);
            }
            try
            {
                using var engine = sb.ToArray().RunTestMode(snapshot);
                //NativeContract.Ledger.
                if (engine.State.HasFlag(VMState.FAULT))
                {
                    Console.WriteLine($"Cannot find Nep5 Asset[{assetId}] at height:{snapshot.GetHeight()}");
                    return(null);
                }
                string name     = contract.Manifest.Name;
                string symbol   = engine.ResultStack.Pop().GetString();
                byte   decimals = (byte)engine.ResultStack.Pop().GetInteger();
                symbol = symbol == "neo" || symbol == "gas" ? symbol.ToUpper() : symbol;

                if (string.IsNullOrWhiteSpace(name))
                {
                    return(null);
                }
                var assetInfo = new AssetInfo()
                {
                    Asset    = assetId,
                    Decimals = decimals,
                    Symbol   = symbol,
                    Name     = name,
                };
                _assets[assetId] = assetInfo;
                return(assetInfo);
            }
            catch (Exception e)
            {
                Console.WriteLine($"Invalid Nep5[{assetId}]:{e}");
                return(null);
            }
        }
Beispiel #23
0
        public byte[] GetScript()
        {
            ECPoint pubkey = (ECPoint)comboBox1.SelectedItem;

            using ScriptBuilder sb = new ScriptBuilder();
            sb.EmitDynamicCall(NativeContract.NEO.Hash, "registerValidator", pubkey);
            return(sb.ToArray());
        }
Beispiel #24
0
        public static IEnumerable <(Nep17Contract contract, BigInteger balance, uint lastUpdatedBlock)> GetNep17Balances(NeoSystem neoSystem, IStorageProvider storageProvider, UInt160 address)
        {
            // assets key is the script hash of the asset contract
            // assets value is the last updated block of the assoicated asset for address
            var assets = new Dictionary <UInt160, uint>();

            foreach (var(blockIndex, _, notification) in GetNep17Transfers(storageProvider))
            {
                var from = ToUInt160(notification.State[0]);
                var to   = ToUInt160(notification.State[1]);

                var fromAddress = notification.State[0].IsNull ? "<null>" : from.ToAddress(neoSystem.Settings.AddressVersion);
                var toAddress   = notification.State[1].IsNull ? "<null>" : to.ToAddress(neoSystem.Settings.AddressVersion);

                if (from == address || to == address)
                {
                    assets[notification.ScriptHash] = blockIndex;
                }
            }

            if (!assets.ContainsKey(NativeContract.NEO.Hash))
            {
                assets[NativeContract.NEO.Hash] = 0;
            }

            if (!assets.ContainsKey(NativeContract.GAS.Hash))
            {
                assets[NativeContract.GAS.Hash] = 0;
            }

            using var snapshot = neoSystem.GetSnapshot();
            foreach (var kvp in assets)
            {
                if (TryGetBalance(kvp.Key, out var balance) &&
                    balance > BigInteger.Zero)
                {
                    var contract = Nep17Contract.TryLoad(neoSystem.Settings, snapshot, kvp.Key, out var _contract)
                        ? _contract : Nep17Contract.Unknown(kvp.Key);
                    yield return(contract, balance, kvp.Value);
                }
            }

            bool TryGetBalance(UInt160 asset, out BigInteger balance)
            {
                using var sb = new ScriptBuilder();
                sb.EmitDynamicCall(asset, "balanceOf", address.ToArray());

                using var engine = sb.Invoke(neoSystem.Settings, snapshot);
                if (!engine.State.HasFlag(VMState.FAULT) && engine.ResultStack.Count >= 1)
                {
                    balance = engine.ResultStack.Pop <Neo.VM.Types.Integer>().GetInteger();
                    return(true);
                }

                balance = default;
                return(false);
            }
        }
Beispiel #25
0
        public byte[] GetScript()
        {
            byte[] script   = textBox8.Text.HexToBytes();
            string manifest = "";

            using ScriptBuilder sb = new ScriptBuilder();
            sb.EmitDynamicCall(NativeContract.ContractManagement.Hash, "deploy", script, manifest);
            return(sb.ToArray());
        }
        void IPersistencePlugin.OnPersist(Block block, DataCache snapshot, IReadOnlyList <Blockchain.ApplicationExecuted> applicationExecutedList)
        {
            // Start freshly with a new DBCache for each block.
            ResetBatch();
            Dictionary <Nep17BalanceKey, Nep17Balance> nep17BalancesChanged = new Dictionary <Nep17BalanceKey, Nep17Balance>();

            ushort transferIndex = 0;

            foreach (Blockchain.ApplicationExecuted appExecuted in applicationExecutedList)
            {
                // Executions that fault won't modify storage, so we can skip them.
                if (appExecuted.VMState.HasFlag(VMState.FAULT))
                {
                    continue;
                }
                foreach (var notifyEventArgs in appExecuted.Notifications)
                {
                    if (!(notifyEventArgs?.State is VM.Types.Array stateItems) || stateItems.Count == 0)
                    {
                        continue;
                    }
                    HandleNotification(snapshot, notifyEventArgs.ScriptContainer, notifyEventArgs.ScriptHash, notifyEventArgs.EventName,
                                       stateItems, nep17BalancesChanged, ref transferIndex);
                }
            }

            foreach (var nep17BalancePair in nep17BalancesChanged)
            {
                // get guarantee accurate balances by calling balanceOf for keys that changed.
                byte[] script;
                using (ScriptBuilder sb = new ScriptBuilder())
                {
                    sb.EmitDynamicCall(nep17BalancePair.Key.AssetScriptHash, "balanceOf", nep17BalancePair.Key.UserScriptHash.ToArray());
                    script = sb.ToArray();
                }

                using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot, gas: 100000000))
                {
                    if (engine.State.HasFlag(VMState.FAULT))
                    {
                        continue;
                    }
                    if (engine.ResultStack.Count <= 0)
                    {
                        continue;
                    }
                    nep17BalancePair.Value.Balance = engine.ResultStack.Pop().GetInteger();
                }
                nep17BalancePair.Value.LastUpdatedBlock = block.Index;
                if (nep17BalancePair.Value.Balance == 0)
                {
                    Delete(Nep17BalancePrefix, nep17BalancePair.Key);
                    continue;
                }
                Put(Nep17BalancePrefix, nep17BalancePair.Key, nep17BalancePair.Value);
            }
        }
Beispiel #27
0
        public static bool TryLoad(DataCache snapshot, UInt160 scriptHash, out Nep17Contract contract)
        {
            if (scriptHash == NativeContract.NEO.Hash)
            {
                contract = new Nep17Contract(
                    NativeContract.NEO.Name,
                    NativeContract.NEO.Symbol,
                    NativeContract.NEO.Decimals,
                    NativeContract.NEO.Hash);
                return(true);
            }

            if (scriptHash == NativeContract.GAS.Hash)
            {
                contract = new Nep17Contract(
                    NativeContract.GAS.Name,
                    NativeContract.GAS.Symbol,
                    NativeContract.GAS.Decimals,
                    NativeContract.GAS.Hash);
                return(true);
            }

            var contractState = NativeContract.ContractManagement.GetContract(snapshot, scriptHash);

            if (contractState != null)
            {
                using var sb = new ScriptBuilder();
                sb.EmitDynamicCall(scriptHash, "symbol");
                sb.EmitDynamicCall(scriptHash, "decimals");

                using var engine = Neo.SmartContract.ApplicationEngine.Run(sb.ToArray(), snapshot);
                if (engine.State != VMState.FAULT && engine.ResultStack.Count >= 2)
                {
                    var decimals = (byte)engine.ResultStack.Pop <Neo.VM.Types.Integer>().GetInteger();
                    var symbol   = Encoding.UTF8.GetString(engine.ResultStack.Pop().GetSpan());
                    contract = new Nep17Contract(contractState.Manifest.Name, symbol, decimals, scriptHash);
                    return(true);
                }
            }

            contract = default;
            return(false);
        }
Beispiel #28
0
        private byte[] LoadDeploymentScript(string nefFilePath, string manifestFilePath, out NefFile nef, out ContractManifest manifest)
        {
            if (string.IsNullOrEmpty(manifestFilePath))
            {
                manifestFilePath = Path.ChangeExtension(nefFilePath, ".manifest.json");
            }

            // Read manifest

            var info = new FileInfo(manifestFilePath);

            if (!info.Exists || info.Length >= Transaction.MaxTransactionSize)
            {
                throw new ArgumentException(nameof(manifestFilePath));
            }

            manifest = ContractManifest.Parse(File.ReadAllBytes(manifestFilePath));

            // Read nef

            info = new FileInfo(nefFilePath);
            if (!info.Exists || info.Length >= Transaction.MaxTransactionSize)
            {
                throw new ArgumentException(nameof(nefFilePath));
            }

            using (var stream = new BinaryReader(File.OpenRead(nefFilePath), Utility.StrictUTF8, false))
            {
                nef = stream.ReadSerializable <NefFile>();
            }

            // Basic script checks

            Script script = new Script(nef.Script);

            for (var i = 0; i < script.Length;)
            {
                // Check bad opcodes

                Instruction inst = script.GetInstruction(i);
                if (inst is null || !Enum.IsDefined(typeof(OpCode), inst.OpCode))
                {
                    throw new FormatException($"OpCode not found at {i}-{((byte)inst.OpCode).ToString("x2")}");
                }
                i += inst.Size;
            }

            // Build script

            using (ScriptBuilder sb = new ScriptBuilder())
            {
                sb.EmitDynamicCall(NativeContract.ContractManagement.Hash, "deploy", nef.ToArray(), manifest.ToJson().ToString());
                return(sb.ToArray());
            }
        }
        /// <summary>
        /// Process "invoke" command
        /// </summary>
        /// <param name="scriptHash">Script hash</param>
        /// <param name="operation">Operation</param>
        /// <param name="result">Result</param>
        /// <param name="verificable">Transaction</param>
        /// <param name="contractParameters">Contract parameters</param>
        /// <returns>Return true if it was successful</returns>
        private bool OnInvokeWithResult(UInt160 scriptHash, string operation, out StackItem result, IVerifiable verificable = null, JArray contractParameters = null, bool showStack = true)
        {
            List <ContractParameter> parameters = new List <ContractParameter>();

            if (contractParameters != null)
            {
                foreach (var contractParameter in contractParameters)
                {
                    parameters.Add(ContractParameter.FromJson(contractParameter));
                }
            }

            bool          hasReturnValue;
            var           snapshot = Blockchain.Singleton.GetSnapshot();
            ContractState contract = NativeContract.ContractManagement.GetContract(snapshot, scriptHash);

            if (contract == null)
            {
                Console.WriteLine("Contract does not exist.");
                result = StackItem.Null;
                return(false);
            }
            else
            {
                if (contract.Manifest.Abi.GetMethod(operation) == null)
                {
                    Console.WriteLine("This method does not not exist in this contract.");
                    result = StackItem.Null;
                    return(false);
                }
                else
                {
                    hasReturnValue = contract.Manifest.Abi.GetMethod(operation).ReturnType != ContractParameterType.Void;
                }
            }

            byte[] script;

            using (ScriptBuilder scriptBuilder = new ScriptBuilder())
            {
                scriptBuilder.EmitDynamicCall(scriptHash, operation, hasReturnValue, parameters.ToArray());
                script = scriptBuilder.ToArray();
                Console.WriteLine($"Invoking script with: '{script.ToBase64String()}'");
            }

            if (verificable is Transaction tx)
            {
                tx.Script = script;
            }

            using ApplicationEngine engine = ApplicationEngine.Run(script, container: verificable);
            PrintExecutionOutput(engine, showStack);
            result = engine.State == VMState.FAULT ? null : engine.ResultStack.Peek();
            return(engine.State != VMState.FAULT);
        }
Beispiel #30
0
        public static BigDecimal?GetTotalSupply(UInt160 asset)
        {
            var snapshot = Helpers.GetDefaultSnapshot();

            using var sb = new ScriptBuilder();
            sb.EmitDynamicCall(asset, "totalSupply");
            using var engine = sb.ToArray().RunTestMode(snapshot);
            var total     = engine.ResultStack.FirstOrDefault().ToBigInteger();
            var assetInfo = GetAssetInfo(asset);

            return(total.HasValue ? new BigDecimal(total.Value, assetInfo.Decimals) : (BigDecimal?)null);
        }