private static Register ConvertFieldToContract(CodeGenerator output, Scope scope, Expression expression) { var literal = expression as LiteralExpression; if (literal == null) { throw new CompilerException("nft argument is not a literal value"); } var module = scope.Module.FindModule(literal.value); var abi = module.abi; if (module.Kind == ModuleKind.NFT) { var nftStandard = NFTUtils.GetNFTStandard(); if (!abi.Implements(nftStandard)) { throw new CompilerException($"nft {literal.value} not does implement NFT standard"); } } var reg = Compiler.Instance.AllocRegister(output, expression); var abiBytes = module.abi.ToByteArray(); output.AppendLine(expression, $"LOAD {reg} 0x{Base16.Encode(abiBytes)} // abi"); output.AppendLine(expression, $"PUSH {reg}"); output.AppendLine(expression, $"LOAD {reg} 0x{Base16.Encode(module.script)} // script"); // output.AppendLine(expression, $"PUSH {reg}"); return(reg); }
public override ContractInterface GenerateCode(CodeGenerator output) { var abi = base.GenerateCode(output); var nftStandard = NFTUtils.GetNFTStandard(); // convert ABI parameters var methods = new List <ContractMethod>(); foreach (var method in abi.Methods) { if (nftStandard.HasMethod(method.name)) { var convertedMethod = new ContractMethod(method.name, method.returnType, method.offset, new[] { new ContractParameter("tokenID", VMType.Number) }); methods.Add(convertedMethod); } else { methods.Add(method); } } abi = new ContractInterface(methods, abi.Events); return(abi); }
public Transaction GenerateToken(PhantasmaKeys owner, string symbol, string name, BigInteger totalSupply, int decimals, TokenFlags flags, byte[] tokenScript = null, Dictionary <string, int> labels = null, IEnumerable <ContractMethod> customMethods = null) { var version = Nexus.GetGovernanceValue(Nexus.RootStorage, Nexus.NexusProtocolVersionTag); if (labels == null) { labels = new Dictionary <string, int>(); } if (tokenScript == null) { // small script that restricts minting of tokens to transactions where the owner is a witness var addressStr = Base16.Encode(owner.Address.ToByteArray()); string[] scriptString; if (version >= 4) { scriptString = new string[] { $"alias r3, $result", $"alias r4, $owner", $"@{AccountTrigger.OnMint}: nop", $"load $owner 0x{addressStr}", "push $owner", "extcall \"Address()\"", "extcall \"Runtime.IsWitness\"", "pop $result", $"jmpif $result, @end", $"load r0 \"invalid witness\"", $"throw r0", $"@end: ret" }; } else { scriptString = new string[] { $"alias r1, $triggerMint", $"alias r2, $currentTrigger", $"alias r3, $result", $"alias r4, $owner", $@"load $triggerMint, ""{AccountTrigger.OnMint}""", $"pop $currentTrigger", $"equal $triggerMint, $currentTrigger, $result", $"jmpif $result, @mintHandler", $"jmp @end", $"@mintHandler: nop", $"load $owner 0x{addressStr}", "push $owner", "extcall \"Address()\"", "extcall \"Runtime.IsWitness\"", "pop $result", $"jmpif $result, @end", $"load r0 \"invalid witness\"", $"throw r0", $"@end: ret" }; } DebugInfo debugInfo; tokenScript = AssemblerUtils.BuildScript(scriptString, "GenerateToken", out debugInfo, out labels); } var sb = ScriptUtils. BeginScript(). AllowGas(owner.Address, Address.Null, MinimumFee, 9999); if (version >= 4) { var triggerMap = new Dictionary <AccountTrigger, int>(); var onMintLabel = AccountTrigger.OnMint.ToString(); if (labels.ContainsKey(onMintLabel)) { triggerMap[AccountTrigger.OnMint] = labels[onMintLabel]; } var methods = AccountContract.GetTriggersForABI(triggerMap); if (customMethods != null) { methods = methods.Concat(customMethods); } var abi = new ContractInterface(methods, Enumerable.Empty <ContractEvent>()); var abiBytes = abi.ToByteArray(); sb.CallInterop("Nexus.CreateToken", owner.Address, symbol, name, totalSupply, decimals, flags, tokenScript, abiBytes); } else { sb.CallInterop("Nexus.CreateToken", owner.Address, symbol, name, totalSupply, decimals, flags, tokenScript); } if (!flags.HasFlag(TokenFlags.Fungible)) { ContractInterface nftABI; byte[] nftScript; NFTUtils.GenerateNFTDummyScript(symbol, name, name, "http://simulator/nft/*", "http://simulator/img/*", out nftScript, out nftABI); sb.CallInterop("Nexus.CreateTokenSeries", owner.Address, symbol, new BigInteger(0), totalSupply, TokenSeriesMode.Unique, nftScript, nftABI.ToByteArray()); } sb.SpendGas(owner.Address); var script = sb.EndScript(); var tx = MakeTransaction(owner, ProofOfWork.Minimal, Nexus.RootChain, script); return(tx); }