Exemplo n.º 1
0
        public bool MigrateMember(RuntimeVM Runtime, Address admin, Address from, Address to)
        {
            Runtime.Expect(Runtime.IsRootChain(), "must be root chain");

            if (to.IsSystem)
            {
                Runtime.Expect(to != this.Address, "can't add organization as member of itself");
            }

            var list = GetMemberList();

            if (!list.Contains <Address>(from))
            {
                return(false);
            }

            Runtime.Expect(!list.Contains <Address>(to), "target address is already a member of organization");

            list.Remove <Address>(from);
            list.Add <Address>(to);

            Runtime.Notify(EventKind.OrganizationRemove, admin, new OrganizationEventData(this.ID, from));
            Runtime.Notify(EventKind.OrganizationAdd, admin, new OrganizationEventData(this.ID, to));

            return(true);
        }
Exemplo n.º 2
0
        public bool AddMember(RuntimeVM Runtime, Address from, Address target)
        {
            if (from.IsSystem)
            {
                Runtime.Expect(from != this.Address, "can't add organization as member of itself");
            }

            Runtime.Expect(Runtime.IsRootChain(), "must be root chain");

            var set = GetMemberSet();

            if (set.Contains <Address>(target))
            {
                return(false);
            }

            set.Add <Address>(target);

            var list = GetMemberList();

            list.Add <Address>(target);

            Runtime.Notify(EventKind.OrganizationAdd, from, new OrganizationEventData(this.ID, target));
            return(true);
        }
Exemplo n.º 3
0
        private static ExecutionState Runtime_Event(RuntimeVM vm)
        {
            var bytes   = vm.Stack.Pop().AsByteArray();
            var address = vm.Stack.Pop().AsInterop <Address>();
            var kind    = vm.Stack.Pop().AsEnum <EventKind>();

            vm.Notify(kind, address, bytes);
            return(ExecutionState.Running);
        }
Exemplo n.º 4
0
        private static ExecutionState Runtime_DeployContract(RuntimeVM Runtime)
        {
            var tx = Runtime.Transaction;

            Throw.IfNull(tx, nameof(tx));

            ExpectStackSize(Runtime, 1);

            VMObject temp;

            var org = Runtime.Nexus.GetChainOrganization(Runtime.Chain.Name);

            var owner = PopAddress(Runtime);

            Runtime.Expect(owner.IsUser, "address must be user");

            if (Runtime.Nexus.HasGenesis)
            {
                //Runtime.Expect(org != DomainSettings.ValidatorsOrganizationName, "cannot deploy contract via this organization");
                Runtime.Expect(Runtime.IsStakeMaster(owner), "needs to be master");
            }

            Runtime.Expect(Runtime.IsWitness(owner), "invalid witness");

            temp = Runtime.Stack.Pop();

            switch (temp.Type)
            {
            case VMType.String:
            {
                var name    = temp.AsString();
                var success = Runtime.Chain.DeployNativeContract(Runtime.Storage, SmartContract.GetAddressForName(name));

                Runtime.Expect(success, name + " contract deploy failed");

                var contract    = Runtime.Nexus.GetContractByName(Runtime.RootStorage, name);
                var constructor = "Initialize";
                if (contract.HasInternalMethod(constructor))
                {
                    Runtime.CallContext(name, constructor, owner);
                }

                Runtime.Notify(EventKind.ContractDeploy, owner, contract.Name);
            }
            break;

            default:
                Runtime.Expect(false, "invalid contract type for deploy");
                break;
            }

            return(ExecutionState.Running);
        }
Exemplo n.º 5
0
        private static ExecutionState Runtime_Notify(RuntimeVM vm)
        {
            vm.Expect(vm.CurrentContext.Name != VirtualMachine.EntryContextName, "cannot notify in current context");

            var kind    = vm.Stack.Pop().AsEnum <EventKind>();
            var address = vm.PopAddress();
            var obj     = vm.Stack.Pop();

            var bytes = obj.Serialize();

            vm.Notify(kind, address, bytes);
            return(ExecutionState.Running);
        }
Exemplo n.º 6
0
        public bool RemoveMember(RuntimeVM Runtime, Address from, Address target)
        {
            var set = GetMemberSet();

            if (!set.Contains <Address>(target))
            {
                return(false);
            }

            set.Remove <Address>(target);
            RemoveMemberFromList(target);

            Runtime.Notify(EventKind.OrganizationRemove, from, target);
            return(true);
        }
Exemplo n.º 7
0
        public bool RemoveMember(RuntimeVM Runtime, Address from, Address target)
        {
            Runtime.Expect(Runtime.IsRootChain(), "must be root chain");

            var list = GetMemberList();

            if (!list.Contains <Address>(target))
            {
                return(false);
            }

            list.Remove <Address>(target);

            Runtime.Notify(EventKind.OrganizationRemove, from, new OrganizationEventData(this.ID, target));
            return(true);
        }
Exemplo n.º 8
0
        public bool AddMember(RuntimeVM Runtime, Address from, Address target)
        {
            var set = GetMemberSet();

            if (set.Contains <Address>(target))
            {
                return(false);
            }

            set.Add <Address>(target);

            var list = GetMemberList();

            list.Add <Address>(target);

            Runtime.Notify(EventKind.OrganizationAdd, from, target);
            return(true);
        }
Exemplo n.º 9
0
        private static ExecutionState Runtime_UpgradeContract(RuntimeVM vm)
        {
            var tx = vm.Transaction;

            Throw.IfNull(tx, nameof(tx));

            var pow = tx.Hash.GetDifficulty();

            vm.Expect(pow >= (int)ProofOfWork.Minimal, "expected proof of work");

            vm.ExpectStackSize(1);

            var from = vm.PopAddress();

            vm.Expect(from.IsUser, "address must be user");

            vm.Expect(vm.IsStakeMaster(from), "needs to be master");

            vm.Expect(vm.IsWitness(from), "invalid witness");

            var contractName = vm.PopString("contractName");

            var contractAddress = SmartContract.GetAddressForName(contractName);
            var deployed        = vm.Chain.IsContractDeployed(vm.Storage, contractAddress);

            vm.Expect(deployed, $"{contractName} does not exist");

            byte[]            script;
            ContractInterface abi;

            bool isNative = Nexus.IsNativeContract(contractName);

            vm.Expect(!isNative, "cannot upgrade native contract");

            bool isToken = ValidationUtils.IsValidTicker(contractName);

            script = vm.PopBytes("contractScript");

            var abiBytes = vm.PopBytes("contractABI");

            abi = ContractInterface.FromBytes(abiBytes);

            var fuelCost = vm.GetGovernanceValue(Nexus.FuelPerContractDeployTag);

            // governance value is in usd fiat, here convert from fiat to fuel amount
            fuelCost = vm.GetTokenQuote(DomainSettings.FiatTokenSymbol, DomainSettings.FuelTokenSymbol, fuelCost);

            // burn the "cost" tokens
            vm.BurnTokens(DomainSettings.FuelTokenSymbol, from, fuelCost);

            // ABI validation
            ValidateABI(vm, contractName, abi, isNative);

            SmartContract oldContract;

            if (isToken)
            {
                oldContract = vm.Nexus.GetTokenContract(vm.Storage, contractName);
            }
            else
            {
                oldContract = vm.Chain.GetContractByName(vm.Storage, contractName);
            }

            vm.Expect(oldContract != null, "could not fetch previous contract");
            vm.Expect(abi.Implements(oldContract.ABI), "new abi does not implement all methods of previous abi");
            vm.Expect(vm.InvokeTrigger(false, script, contractName, abi, AccountTrigger.OnUpgrade.ToString(), from) == TriggerResult.Success, "OnUpgrade trigger failed");

            if (isToken)
            {
                vm.Nexus.UpgradeTokenContract(vm.RootStorage, contractName, script, abi);
            }
            else
            {
                vm.Chain.UpgradeContract(vm.Storage, contractName, script, abi);
            }

            vm.Notify(EventKind.ContractUpgrade, from, contractName);

            return(ExecutionState.Running);
        }
Exemplo n.º 10
0
        private static ExecutionState Runtime_DeployContract(RuntimeVM vm)
        {
            var tx = vm.Transaction;

            Throw.IfNull(tx, nameof(tx));

            var pow = tx.Hash.GetDifficulty();

            vm.Expect(pow >= (int)ProofOfWork.Minimal, "expected proof of work");

            vm.ExpectStackSize(1);

            var from = vm.PopAddress();

            vm.Expect(from.IsUser, "address must be user");

            if (vm.Nexus.HasGenesis)
            {
                //Runtime.Expect(org != DomainSettings.ValidatorsOrganizationName, "cannot deploy contract via this organization");
                vm.Expect(vm.IsStakeMaster(from), "needs to be master");
            }

            vm.Expect(vm.IsWitness(from), "invalid witness");

            var contractName = vm.PopString("contractName");

            var contractAddress = SmartContract.GetAddressForName(contractName);
            var deployed        = vm.Chain.IsContractDeployed(vm.Storage, contractAddress);

            // TODO
            if (vm.ProtocolVersion >= 2)
            {
                vm.Expect(!deployed, $"{contractName} is already deployed");
            }
            else
            if (deployed)
            {
                return(ExecutionState.Running);
            }

            byte[]            script;
            ContractInterface abi;

            bool isNative = Nexus.IsNativeContract(contractName);

            if (isNative)
            {
                if (contractName == "validator" && vm.GenesisAddress == Address.Null)
                {
                    vm.Nexus.Initialize(from);
                }

                script = new byte[] { (byte)Opcode.RET };

                var contractInstance = vm.Nexus.GetNativeContractByAddress(contractAddress);
                abi = contractInstance.ABI;
            }
            else
            {
                if (ValidationUtils.IsValidTicker(contractName))
                {
                    throw new VMException(vm, "use createToken instead for this kind of contract");
                }
                else
                {
                    vm.Expect(ValidationUtils.IsValidIdentifier(contractName), "invalid contract name");
                }

                var isReserved = ValidationUtils.IsReservedIdentifier(contractName);

                if (isReserved && vm.IsWitness(vm.GenesisAddress))
                {
                    isReserved = false;
                }

                vm.Expect(!isReserved, $"name '{contractName}' reserved by system");

                script = vm.PopBytes("contractScript");

                var abiBytes = vm.PopBytes("contractABI");
                abi = ContractInterface.FromBytes(abiBytes);

                var fuelCost = vm.GetGovernanceValue(Nexus.FuelPerContractDeployTag);
                // governance value is in usd fiat, here convert from fiat to fuel amount
                fuelCost = vm.GetTokenQuote(DomainSettings.FiatTokenSymbol, DomainSettings.FuelTokenSymbol, fuelCost);

                // burn the "cost" tokens
                vm.BurnTokens(DomainSettings.FuelTokenSymbol, from, fuelCost);
            }

            // ABI validation
            ValidateABI(vm, contractName, abi, isNative);

            var success = vm.Chain.DeployContractScript(vm.Storage, from, contractName, contractAddress, script, abi);

            vm.Expect(success, $"deployment of {contractName} failed");

            var constructor = abi.FindMethod(SmartContract.ConstructorName);

            if (constructor != null)
            {
                vm.CallContext(contractName, constructor, from);
            }

            vm.Notify(EventKind.ContractDeploy, from, contractName);

            return(ExecutionState.Running);
        }