Пример #1
0
        public async Task <object> DeployContract(string nefPath, string manifestPath = null, bool sendTx = false, UInt160 sender = null)
        {
            if (CurrentWallet == null)
            {
                return(Error(ErrorCode.WalletNotOpen));
            }
            if (nefPath.IsNull())
            {
                return(Error(ErrorCode.ParameterIsNull, "nefPath is empty."));
            }
            if (manifestPath.IsNull())
            {
                manifestPath = Path.ChangeExtension(nefPath, ".manifest.json");
            }
            // Read nef
            NefFile nefFile = ReadNefFile(nefPath);
            // Read manifest
            ContractManifest manifest = ReadManifestFile(manifestPath);

            // Basic script checks
            await CheckBadOpcode(nefFile.Script);

            // Build script
            using ScriptBuilder sb = new ScriptBuilder();
            sb.EmitDynamicCall(NativeContract.ContractManagement.Hash, "deploy", nefFile.ToArray(),
                               manifest.ToJson().ToString());
            //sb.EmitAppCall(NativeContract.Management.Hash, "deploy", nefFile.ToArray(), manifest.ToJson().ToString());
            var script = sb.ToArray();

            Transaction tx;

            try
            {
                tx = CurrentWallet.MakeTransaction(Helpers.GetDefaultSnapshot(), script, sender);
            }
            catch (InvalidOperationException ex)
            {
                return(Error(ErrorCode.EngineFault, ex.GetExMessage()));
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("Insufficient GAS"))
                {
                    return(Error(ErrorCode.GasNotEnough));
                }
                throw;
            }

            UInt160 hash = SmartContract.Helper.GetContractHash(tx.Sender, nefFile.CheckSum, manifest.Name);

            var oldContract = hash.GetContract();

            if (oldContract != null)
            {
                return(Error(ErrorCode.ContractAlreadyExist));
            }
            var result = new DeployResultModel
            {
                ContractHash = hash,
                GasConsumed  = new BigDecimal((BigInteger)tx.SystemFee, NativeContract.GAS.Decimals)
            };

            if (sendTx)
            {
                var(signSuccess, context) = CurrentWallet.TrySignTx(tx);
                if (!signSuccess)
                {
                    return(Error(ErrorCode.SignFail, context.SafeSerialize()));
                }
                await tx.Broadcast();

                result.TxId = tx.Hash;
            }
            return(result);
        }
Пример #2
0
        public async Task <object> DeployContract(string nefPath, string manifestPath = null, bool sendTx = false)
        {
            if (CurrentWallet == null)
            {
                return(Error(ErrorCode.WalletNotOpen));
            }
            if (nefPath.IsNull())
            {
                return(Error(ErrorCode.ParameterIsNull, "nefPath is empty."));
            }
            if (manifestPath.IsNull())
            {
                manifestPath = Path.ChangeExtension(nefPath, ".manifest.json");
            }
            // Read nef
            NefFile nefFile = ReadNefFile(nefPath);


            using var snapshot = Blockchain.Singleton.GetSnapshot();
            var oldContract = snapshot.Contracts.TryGet(nefFile.ScriptHash);

            if (oldContract != null)
            {
                return(Error(ErrorCode.ContractAlreadyExist));
            }
            // Read manifest
            ContractManifest manifest = ReadManifestFile(manifestPath);

            // Basic script checks
            await CheckBadOpcode(nefFile.Script);

            // Build script
            using ScriptBuilder sb = new ScriptBuilder();
            sb.EmitSysCall(InteropService.Contract.Create, nefFile.Script, manifest.ToJson().ToString());
            var script = sb.ToArray();

            Transaction tx;

            try
            {
                tx = CurrentWallet.MakeTransaction(script);
            }
            catch (InvalidOperationException)
            {
                return(Error(ErrorCode.EngineFault));
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("Insufficient GAS"))
                {
                    return(Error(ErrorCode.GasNotEnough));
                }
                throw;
            }

            var result = new DeployResultModel
            {
                ContractHash = nefFile.ScriptHash,
                GasConsumed  = new BigDecimal(tx.SystemFee, NativeContract.GAS.Decimals)
            };

            if (sendTx)
            {
                var(signSuccess, context) = CurrentWallet.TrySignTx(tx);
                if (!signSuccess)
                {
                    return(Error(ErrorCode.SignFail, context.SafeSerialize()));
                }
                await tx.Broadcast();

                result.TxId = tx.Hash;
            }
            return(result);
        }
Пример #3
0
        public async Task <object> UpdateContract(UInt160 contractHash, string nefPath, string manifestPath = null, bool sendTx = false, UInt160[] cosigners = null)
        {
            if (CurrentWallet == null)
            {
                return(Error(ErrorCode.WalletNotOpen));
            }
            if (nefPath.IsNull())
            {
                return(Error(ErrorCode.ParameterIsNull, "nefPath is empty."));
            }
            if (manifestPath.IsNull())
            {
                manifestPath = Path.ChangeExtension(nefPath, ".manifest.json");
            }
            // Read nef
            NefFile nefFile = ReadNefFile(nefPath);
            // Read manifest
            ContractManifest manifest = ReadManifestFile(manifestPath);

            // Basic script checks
            await CheckBadOpcode(nefFile.Script);

            // Build script
            using ScriptBuilder sb = new ScriptBuilder();
            sb.EmitDynamicCall(contractHash, "update", nefFile.ToArray(), manifest.ToJson().ToString(), null);
            var script = sb.ToArray();

            var singers = new List <Signer> {
            };

            if (cosigners != null)
            {
                singers.AddRange(cosigners.Select(s => new Signer()
                {
                    Account = s, Scopes = WitnessScope.Global
                }));
            }
            Transaction tx;

            try
            {
                tx = CurrentWallet.MakeTransaction(Helpers.GetDefaultSnapshot(), script, null, singers.ToArray());
            }
            catch (InvalidOperationException ex)
            {
                return(Error(ErrorCode.EngineFault, ex.GetExMessage()));
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("Insufficient GAS"))
                {
                    return(Error(ErrorCode.GasNotEnough));
                }
                throw;
            }

            var result = new DeployResultModel
            {
                ContractHash = contractHash,
                GasConsumed  = new BigDecimal((BigInteger)tx.SystemFee, NativeContract.GAS.Decimals)
            };

            if (sendTx)
            {
                var(signSuccess, context) = CurrentWallet.TrySignTx(tx);
                if (!signSuccess)
                {
                    return(Error(ErrorCode.SignFail, context.SafeSerialize()));
                }
                await tx.Broadcast();

                result.TxId = tx.Hash;
            }
            return(result);
        }