Esempio n. 1
0
        public bool DeployContractScript(StorageContext storage, Address contractOwner, string name, Address contractAddress, byte[] script, ContractInterface abi)
        {
            var scriptKey = GetContractKey(contractAddress, "script");

            if (storage.Has(scriptKey))
            {
                return(false);
            }

            storage.Put(scriptKey, script);

            var ownerBytes = contractOwner.ToByteArray();
            var ownerKey   = GetContractKey(contractAddress, "owner");

            storage.Put(ownerKey, ownerBytes);

            var abiBytes = abi.ToByteArray();
            var abiKey   = GetContractKey(contractAddress, "abi");

            storage.Put(abiKey, abiBytes);

            var nameBytes = Encoding.ASCII.GetBytes(name);
            var nameKey   = GetContractKey(contractAddress, "name");

            storage.Put(nameKey, nameBytes);

            var contractList = new StorageList(GetContractListKey(), storage);

            contractList.Add <Address>(contractAddress);

            return(true);
        }
Esempio n. 2
0
        public void UpgradeContract(StorageContext storage, string name, byte[] script, ContractInterface abi)
        {
            if (Nexus.IsNativeContract(name) || ValidationUtils.IsValidTicker(name))
            {
                throw new ChainException($"Cannot upgrade this type of contract: {name}");
            }

            if (!IsContractDeployed(storage, name))
            {
                throw new ChainException($"Cannot upgrade non-existing contract: {name}");
            }

            var address = SmartContract.GetAddressForName(name);

            var scriptKey = GetContractKey(address, "script");

            storage.Put(scriptKey, script);

            var abiKey   = GetContractKey(address, "abi");
            var abiBytes = abi.ToByteArray();

            storage.Put(abiBytes, abiBytes);
        }
Esempio n. 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);
        }
Esempio n. 4
0
        static byte[] GenCreateToken()
        {
            Console.Write("Token symbol? ");
            string symbol = Console.ReadLine();

            if (!ValidationUtils.IsValidTicker(symbol))
            {
                Console.Write("Invalid token symbol");
                return(null);
            }

            Console.Write("Token name? ");
            string name = Console.ReadLine();

            TokenFlags flags = TokenFlags.Transferable;

            var possibleValues = new[] { TokenFlags.Burnable, TokenFlags.Divisible, TokenFlags.Finite, TokenFlags.Fungible };

            foreach (var val in possibleValues)
            {
                if (FetchAnswer($"Is {symbol} {val}?"))
                {
                    flags |= val;
                }
            }

            int decimals;

            if (flags.HasFlag(TokenFlags.Divisible))
            {
                Console.Write($"How many decimals {symbol} has?: ");
                if (!int.TryParse(Console.ReadLine(), out decimals) || decimals < 0 || decimals > 18)
                {
                    Console.Write("Invalid decimals");
                    return(null);
                }
            }
            else
            {
                decimals = 0;
            }

            BigInteger maxSupply;

            if (flags.HasFlag(TokenFlags.Finite))
            {
                Console.Write($"What is the max supply of {symbol}?: ");

                decimal val;
                if (!decimal.TryParse(Console.ReadLine(), out val) || val <= 0)
                {
                    Console.Write("Invalid decimals");
                    return(null);
                }

                maxSupply = UnitConversion.ToBigInteger(val, decimals);
            }
            else
            {
                maxSupply = 0;
            }


            var labels     = new Dictionary <string, int>();
            var addressStr = Base16.Encode(signerKeys.Address.ToByteArray());

            string[] scriptString;

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

            DebugInfo debugInfo;
            var       tokenScript = AssemblerUtils.BuildScript(scriptString, "GenerateToken", out debugInfo, out labels);

            var sb = ScriptUtils.
                     BeginScript().
                     AllowGas(signerKeys.Address, Address.Null, MinimumFee, 9999);

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

            var abi      = new ContractInterface(methods, Enumerable.Empty <ContractEvent>());
            var abiBytes = abi.ToByteArray();

            sb.CallInterop("Nexus.CreateToken", signerKeys.Address, symbol, name, maxSupply, decimals, flags, tokenScript, abiBytes);

            if (!flags.HasFlag(TokenFlags.Fungible))
            {
                Console.Write("NFT deployment not supported yet");
                return(null);
            }

            sb.SpendGas(signerKeys.Address);

            var script = sb.EndScript();


            return(script);
        }