Exemplo n.º 1
0
        public BSCInterop(TokenSwapper swapper, EthAPI ethAPI, PBigInteger interopBlockHeight, string[] contracts, uint confirmations)
            : base(swapper, BSCWallet.BSCPlatform)
        {
            string lastBlockHeight = OracleReader.GetCurrentHeight(BSCWallet.BSCPlatform, BSCWallet.BSCPlatform);

            if (string.IsNullOrEmpty(lastBlockHeight))
            {
                OracleReader.SetCurrentHeight(BSCWallet.BSCPlatform, BSCWallet.BSCPlatform, new BigInteger(interopBlockHeight.ToSignedByteArray()).ToString());
            }

            Logger.Message($"interopHeight: {OracleReader.GetCurrentHeight(BSCWallet.BSCPlatform, BSCWallet.BSCPlatform)}");
            Console.WriteLine("encoded bsc: " + BSCWallet.EncodeAddress("0x44E8743A6CAC3E59594C19DD462863A5AA5E06BB"));
            Console.WriteLine("encoded eth: " + EthereumWallet.EncodeAddress("0x44E8743A6CAC3E59594C19DD462863A5AA5E06BB"));

            Console.WriteLine("from encoded bsc: " + BSCWallet.EncodeAddress("0xA89a34c37Da826085E458c17067DA2F38b6e4763"));
            Console.WriteLine("from encoded eth: " + EthereumWallet.EncodeAddress("0xA89a34c37Da826085E458c17067DA2F38b6e4763"));

            this.contracts = contracts.ToList();

            // add local swap address to contracts
            this.contracts.Add(LocalAddress);

            this.confirmations = confirmations;
            this.ethAPI        = ethAPI;
        }
Exemplo n.º 2
0
        public static Tuple <InteropBlock, InteropTransaction[]> MakeInteropBlock(Nexus nexus, Logger logger, EthAPI api
                                                                                  , BigInteger height, string[] contracts, uint confirmations, string[] swapAddress)
        {
            Hash blockHash           = Hash.Null;
            var  interopTransactions = new List <InteropTransaction>();

            //TODO HACK
            var combinedAddresses = contracts.ToList();

            combinedAddresses.AddRange(swapAddress);

            Dictionary <string, Dictionary <string, List <InteropTransfer> > > transfers = new Dictionary <string, Dictionary <string, List <InteropTransfer> > >();

            try
            {
                // TODO pass from outside to not instantiate for each call to MakeInteropBlock
                Func <string, Address> addressEncoder = (address) => { return(BSCWallet.EncodeAddress(address)); };
                Func <Nethereum.RPC.Eth.DTOs.Transaction, Address> addressExtractor = (tx) => { return(BSCInterop.ExtractInteropAddress(tx)); };

                var crawler = new EvmBlockCrawler(logger, combinedAddresses.ToArray(), confirmations, api,
                                                  addressEncoder, addressExtractor, BSCWallet.BSCPlatform);
                // fetch blocks
                crawler.Fetch(height);
                transfers = crawler.ExtractInteropTransfers(nexus, logger, swapAddress);
            }
            catch (Exception e)
            {
                logger.Error("Failed to fetch eth blocks: " + e);
            }

            if (transfers.Count == 0)
            {
                var emptyBlock = new InteropBlock(BSCWallet.BSCPlatform, BSCWallet.BSCPlatform, Hash.Null, new Hash[] {});
                return(Tuple.Create(emptyBlock, interopTransactions.ToArray()));
            }

            blockHash = Hash.Parse(transfers.FirstOrDefault().Key);

            foreach (var block in transfers)
            {
                var txTransferDict = block.Value;
                foreach (var tx in txTransferDict)
                {
                    var interopTx = MakeInteropTx(logger, tx.Key, tx.Value);
                    if (interopTx.Hash != Hash.Null)
                    {
                        interopTransactions.Add(interopTx);
                    }
                }
            }

            var hashes = interopTransactions.Select(x => x.Hash).ToArray();

            InteropBlock interopBlock = (interopTransactions.Count() > 0)
                ? new InteropBlock(BSCWallet.BSCPlatform, BSCWallet.BSCPlatform, blockHash, hashes)
                : new InteropBlock(BSCWallet.BSCPlatform, BSCWallet.BSCPlatform, Hash.Null, hashes);

            return(Tuple.Create(interopBlock, interopTransactions.ToArray()));
        }
Exemplo n.º 3
0
        protected void OnPlatformAddressAdd(string[] args)
        {
            var platform        = args[0];
            var externalAddress = args[1];

            Address localAddress;

            switch (platform)
            {
            case NeoWallet.NeoPlatform:
                localAddress = NeoWallet.EncodeAddress(externalAddress);
                break;

            case EthereumWallet.EthereumPlatform:
                localAddress = EthereumWallet.EncodeAddress(externalAddress);
                break;

            case BSCWallet.BSCPlatform:
                localAddress = BSCWallet.EncodeAddress(externalAddress);
                break;

            default:
                throw new Exception("Unknown platform: " + platform);
            }

            var minimumFee = _cli.Settings.Node.MinimumFee;
            var script     = ScriptUtils.BeginScript()
                             .AllowGas(_cli.NodeKeys.Address, Address.Null, minimumFee, 1500)
                             .CallContract("interop", nameof(InteropContract.RegisterAddress), _cli.NodeKeys.Address, platform, localAddress, externalAddress)
                             .SpendGas(_cli.NodeKeys.Address).EndScript();

            var expire = Timestamp.Now + TimeSpan.FromMinutes(2);
            var tx     = new Phantasma.Blockchain.Transaction(_cli.Nexus.Name, _cli.Nexus.RootChain.Name, script, expire, Spook.TxIdentifier);

            tx.Mine((int)ProofOfWork.Minimal);
            tx.Sign(_cli.NodeKeys);

            if (_cli.Mempool != null)
            {
                _cli.Mempool.Submit(tx);
                Console.WriteLine($"Transaction {tx.Hash} submitted to mempool.");
            }
            else
            {
                Console.WriteLine("No mempool available");
                return;
            }
            Console.WriteLine($"Added address {externalAddress} to {platform}");
            Spook.Logger.Message($"Added address {externalAddress} to {platform}");
        }
Exemplo n.º 4
0
        // NOTE no locks happen here because this callback is called from within a lock
        internal override Hash SettleSwap(Hash sourceHash, Address destination, IToken token, Numerics.BigInteger amount)
        {
            // check if tx was sent but not minded yet
            string tx = null;

            var inProgressMap = new StorageMap(TokenSwapper.InProgressTag, Swapper.Storage);

            if (inProgressMap.ContainsKey <Hash>(sourceHash))
            {
                tx = inProgressMap.Get <Hash, string>(sourceHash);

                if (!string.IsNullOrEmpty(tx))
                {
                    return(VerifyBscTx(sourceHash, tx));
                }
            }

            var total = Numerics.UnitConversion.ToDecimal(amount, token.Decimals);

            var bscKeys = EthereumKey.FromWIF(this.WIF);

            var destAddress = BSCWallet.DecodeAddress(destination);

            try
            {
                Logger.Debug($"BSCSWAP: Trying transfer of {total} {token.Symbol} from {bscKeys.Address} to {destAddress}");
                var transferResult = ethAPI.TryTransferAsset(BSCWallet.BSCPlatform, token.Symbol, destAddress, total, token.Decimals, out tx);

                if (transferResult == EthTransferResult.Success)
                {
                    // persist resulting tx hash as in progress
                    inProgressMap.Set <Hash, string>(sourceHash, tx);
                    Logger.Debug("broadcasted eth tx: " + tx);
                }
                else
                {
                    Logger.Error($"BSCSWAP: Transfer of {total} {token.Symbol} from {bscKeys.Address} to {destAddress} failed, no tx generated");
                }
            }
            catch (Exception e)
            {
                Logger.Error($"Exception during transfer: {e}");
                // we don't know if the transfer happend or not, therefore can't delete from inProgressMap yet.
                return(Hash.Null);
            }

            return(VerifyBscTx(sourceHash, tx));
        }
Exemplo n.º 5
0
        private static Dictionary <string, List <InteropTransfer> > GetInteropTransfers(Nexus nexus, Logger logger,
                                                                                        TransactionReceipt txr, EthAPI api, string[] swapAddresses)
        {
            logger.Debug($"get interop transfers for tx {txr.TransactionHash}");
            var interopTransfers = new Dictionary <string, List <InteropTransfer> >();

            Nethereum.RPC.Eth.DTOs.Transaction tx = null;
            try
            {
                // tx to get the eth transfer if any
                tx = api.GetTransaction(txr.TransactionHash);
            }
            catch (Exception e)
            {
                logger.Error("Getting eth tx failed: " + e.Message);
            }

            Console.WriteLine("txr: " + txr.Status);
            logger.Debug("Transaction status: " + txr.Status.Value);
            // check if tx has failed
            if (txr.Status.Value == 0)
            {
                logger.Error($"tx {txr.TransactionHash} failed");
                return(interopTransfers);
            }

            foreach (var a in swapAddresses)
            {
                Console.WriteLine("swap address: " + a);
            }
            var nodeSwapAddresses = swapAddresses.Select(x => BSCWallet.EncodeAddress(x));
            var interopAddress    = ExtractInteropAddress(tx);

            Console.WriteLine("interop address: " + interopAddress);

            // ERC721 (NFT)
            // TODO currently this code block is mostly copypaste from BEP20 block, later make a single method for both...
            //var erc721_events = txr.DecodeAllEvents<Nethereum.StandardNonFungibleTokenERC721.ContractDefinition.TransferEventDTOBase>();
            //foreach (var evt in erc721_events)
            //{
            //    var asset = EthUtils.FindSymbolFromAsset(nexus, evt.Log.Address);
            //    if (asset == null)
            //    {
            //        logger.Warning($"Asset [{evt.Log.Address}] not supported");
            //        continue;
            //    }

            //    var targetAddress = BSCWallet.EncodeAddress(evt.Event.To);
            //    var sourceAddress = BSCWallet.EncodeAddress(evt.Event.From);
            //    var tokenID = PBigInteger.Parse(evt.Event.TokenId.ToString());

            //    if (nodeSwapAddresses.Contains(targetAddress))
            //    {
            //        if (!interopTransfers.ContainsKey(evt.Log.TransactionHash))
            //        {
            //            interopTransfers.Add(evt.Log.TransactionHash, new List<InteropTransfer>());
            //        }

            //        string tokenURI = FetchTokenURI(evt.Log.Address, evt.Event.TokenId);

            //        interopTransfers[evt.Log.TransactionHash].Add
            //        (
            //            new InteropTransfer
            //            (
            //                BSCWallet.BSCPlatform,
            //                sourceAddress,
            //                DomainSettings.PlatformName,
            //                targetAddress,
            //                interopAddress,
            //                asset,
            //                tokenID,
            //                System.Text.Encoding.UTF8.GetBytes(tokenURI)
            //            )
            //        );
            //    }
            //}

            // BEP20
            var bep20_events = txr.DecodeAllEvents <TransferEventDTO>();

            foreach (var evt in bep20_events)
            {
                var asset = EthUtils.FindSymbolFromAsset(BSCWallet.BSCPlatform, nexus, evt.Log.Address);
                if (asset == null)
                {
                    logger.Warning($"Asset [{evt.Log.Address}] not supported");
                    continue;
                }

                var targetAddress = BSCWallet.EncodeAddress(evt.Event.To);
                var sourceAddress = BSCWallet.EncodeAddress(evt.Event.From);
                var amount        = PBigInteger.Parse(evt.Event.Value.ToString());

                if (nodeSwapAddresses.Contains(targetAddress))
                {
                    if (!interopTransfers.ContainsKey(evt.Log.TransactionHash))
                    {
                        interopTransfers.Add(evt.Log.TransactionHash, new List <InteropTransfer>());
                    }

                    interopTransfers[evt.Log.TransactionHash].Add
                    (
                        new InteropTransfer
                        (
                            BSCWallet.BSCPlatform,
                            sourceAddress,
                            DomainSettings.PlatformName,
                            targetAddress,
                            interopAddress,
                            asset,
                            amount
                        )
                    );
                }
            }

            Console.WriteLine("value: " + tx.Value);
            Console.WriteLine("value: " + tx.Value.Value);
            if (tx.Value != null && tx.Value.Value > 0)
            {
                var targetAddress = BSCWallet.EncodeAddress(tx.To);
                var sourceAddress = BSCWallet.EncodeAddress(tx.From);

                foreach (var a in nodeSwapAddresses)
                {
                    Console.WriteLine("node swap address: " + a);
                }
                Console.WriteLine("target address: " + targetAddress);

                if (nodeSwapAddresses.Contains(targetAddress))
                {
                    var amount = PBigInteger.Parse(tx.Value.ToString());

                    if (!interopTransfers.ContainsKey(tx.TransactionHash))
                    {
                        interopTransfers.Add(tx.TransactionHash, new List <InteropTransfer>());
                    }

                    interopTransfers[tx.TransactionHash].Add
                    (
                        new InteropTransfer
                        (
                            BSCWallet.BSCPlatform,
                            sourceAddress,
                            DomainSettings.PlatformName,
                            targetAddress,
                            interopAddress,
                            "BSC", // TODO use const
                            amount
                        )
                    );
                }
            }


            return(interopTransfers);
        }