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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }