private ContractTask Update(ApplicationEngine engine, byte[] nefFile, byte[] manifest, StackItem data) { if (nefFile is null && manifest is null) throw new ArgumentException(); engine.AddValt(engine.StoragePrice * ((nefFile?.Length ?? 0) + (manifest?.Length ?? 0))); var contract = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_Contract).Add(engine.CallingScriptHash))?.GetInteroperable<ContractState>(); if (contract is null) throw new InvalidOperationException($"Updating Contract Does Not Exist: {engine.CallingScriptHash}"); if (nefFile != null) { if (nefFile.Length == 0) throw new ArgumentException($"Invalid NefFile Length: {nefFile.Length}"); // Update nef contract.Nef = nefFile.AsSerializable<NefFile>(); } if (manifest != null) { if (manifest.Length == 0) throw new ArgumentException($"Invalid Manifest Length: {manifest.Length}"); ContractManifest manifest_new = ContractManifest.Parse(manifest); if (manifest_new.Name != contract.Manifest.Name) throw new InvalidOperationException("The name of the contract can't be changed."); if (!manifest_new.IsValid(contract.Hash)) throw new InvalidOperationException($"Invalid Manifest Hash: {contract.Hash}"); contract.Manifest = manifest_new; } Helper.Check(contract.Nef.Script, contract.Manifest.Abi); contract.UpdateCounter++; // Increase update counter return OnDeploy(engine, contract, data, true); }
private bool RegisterCandidate(ApplicationEngine engine, ECPoint pubkey) { if (!engine.CheckWitnessInternal(Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash())) { return(false); } engine.AddValt(GetRegisterPrice(engine.Snapshot)); StorageKey key = CreateStorageKey(Prefix_Candidate).Add(pubkey); StorageItem item = engine.Snapshot.GetAndChange(key, () => new StorageItem(new CandidateState())); CandidateState state = item.GetInteroperable <CandidateState>(); state.Registered = true; return(true); }
private async ContractTask<ContractState> Deploy(ApplicationEngine engine, byte[] nefFile, byte[] manifest, StackItem data) { if (engine.ScriptContainer is not Transaction tx) throw new InvalidOperationException(); if (nefFile.Length == 0) throw new ArgumentException($"Invalid NefFile Length: {nefFile.Length}"); if (manifest.Length == 0) throw new ArgumentException($"Invalid Manifest Length: {manifest.Length}"); engine.AddValt(Math.Max( engine.StoragePrice * (nefFile.Length + manifest.Length), GetMinimumDeploymentFee(engine.Snapshot) )); NefFile nef = nefFile.AsSerializable<NefFile>(); ContractManifest parsedManifest = ContractManifest.Parse(manifest); Helper.Check(nef.Script, parsedManifest.Abi); UInt160 hash = Helper.GetContractHash(tx.Sender, nef.CheckSum, parsedManifest.Name); StorageKey key = CreateStorageKey(Prefix_Contract).Add(hash); if (engine.Snapshot.Contains(key)) throw new InvalidOperationException($"Contract Already Exists: {hash}"); ContractState contract = new() { Id = GetNextAvailableId(engine.Snapshot), UpdateCounter = 0, Nef = nef, Hash = hash, Manifest = parsedManifest }; if (!contract.Manifest.IsValid(hash)) throw new InvalidOperationException($"Invalid Manifest Hash: {hash}"); engine.Snapshot.Add(key, new StorageItem(contract)); await OnDeploy(engine, contract, data, false); return contract; }