示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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);
        }