Exemple #1
0
        public override Empty CrossChainReceiveToken(CrossChainReceiveTokenInput input)
        {
            var transferTransaction     = Transaction.Parser.ParseFrom(input.TransferTransactionBytes);
            var transferTransactionHash = transferTransaction.GetHash();

            Context.LogDebug(() => $"transferTransactionHash == {transferTransactionHash}");
            Assert(State.VerifiedCrossChainTransferTransaction[transferTransactionHash] == null,
                   "Token already claimed.");

            var crossChainTransferInput =
                CrossChainTransferInput.Parser.ParseFrom(transferTransaction.Params.ToByteArray());
            var symbol           = crossChainTransferInput.TokenInfo.Symbol;
            var amount           = crossChainTransferInput.Amount;
            var receivingAddress = crossChainTransferInput.To;
            var targetChainId    = crossChainTransferInput.ToChainId;

            Context.LogDebug(() =>
                             $"symbol == {symbol}, amount == {amount}, receivingAddress == {receivingAddress}, targetChainId == {targetChainId}");

            Assert(receivingAddress.Equals(Context.Sender) && targetChainId == Context.ChainId,
                   "Unable to receive cross chain token.");
            if (State.CrossChainContractReferenceState.Value == null)
            {
                State.CrossChainContractReferenceState.Value =
                    State.BasicContractZero.GetContractAddressByName.Call(State.CrossChainContractSystemName.Value);
            }
            var verificationInput = new VerifyTransactionInput
            {
                TransactionId     = transferTransactionHash,
                ParentChainHeight = input.ParentChainHeight,
                VerifiedChainId   = input.FromChainId
            };

            verificationInput.Path.AddRange(input.MerklePath);
            if (State.CrossChainContractReferenceState.Value == null)
            {
                State.CrossChainContractReferenceState.Value =
                    State.BasicContractZero.GetContractAddressByName.Call(State.CrossChainContractSystemName.Value);
            }
            var verificationResult =
                State.CrossChainContractReferenceState.VerifyTransaction.Call(verificationInput);

            Assert(verificationResult.Value, "Verification failed.");

            // Create token if it doesnt exist.
            var existing = State.TokenInfos[symbol];

            if (existing == null)
            {
                RegisterTokenInfo(crossChainTransferInput.TokenInfo);
            }

            State.VerifiedCrossChainTransferTransaction[transferTransactionHash] = input;
            var balanceOfReceiver = State.Balances[receivingAddress][symbol];

            State.Balances[receivingAddress][symbol] = balanceOfReceiver.Add(amount);
            return(new Empty());
        }
Exemple #2
0
        /// <summary>
        /// Receive the token from another chain
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public override Empty CrossChainReceiveToken(CrossChainReceiveTokenInput input)
        {
            var transferTransaction   = Transaction.Parser.ParseFrom(input.TransferTransactionBytes);
            var transferTransactionId = transferTransaction.GetHash();

            Assert(!State.VerifiedCrossChainTransferTransaction[transferTransactionId],
                   "Token already claimed.");

            var crossChainTransferInput =
                CrossChainTransferInput.Parser.ParseFrom(transferTransaction.Params.ToByteArray());
            var symbol           = crossChainTransferInput.Symbol;
            var amount           = crossChainTransferInput.Amount;
            var receivingAddress = crossChainTransferInput.To;
            var targetChainId    = crossChainTransferInput.ToChainId;
            var transferSender   = transferTransaction.From;

            var tokenInfo    = AssertValidToken(symbol, amount);
            int issueChainId = GetIssueChainId(symbol);

            Assert(issueChainId == crossChainTransferInput.IssueChainId, "Incorrect issue chain id.");
            Assert(transferSender == Context.Sender && targetChainId == Context.ChainId,
                   "Unable to claim cross chain token.");
            var registeredTokenContractAddress = State.CrossChainTransferWhiteList[input.FromChainId];

            AssertCrossChainTransaction(transferTransaction, registeredTokenContractAddress,
                                        nameof(CrossChainTransfer));
            Context.LogDebug(() =>
                             $"symbol == {symbol}, amount == {amount}, receivingAddress == {receivingAddress}, targetChainId == {targetChainId}");

            CrossChainVerify(transferTransactionId, input.ParentChainHeight, input.FromChainId, input.MerklePath);

            State.VerifiedCrossChainTransferTransaction[transferTransactionId] = true;
            tokenInfo.Supply = tokenInfo.Supply.Add(amount);
            Assert(tokenInfo.Supply <= tokenInfo.TotalSupply, "Total supply exceeded");
            State.TokenInfos[symbol] = tokenInfo;
            ModifyBalance(receivingAddress, symbol, amount);

            Context.Fire(new CrossChainReceived
            {
                From              = transferSender,
                To                = receivingAddress,
                Symbol            = symbol,
                Amount            = amount,
                Memo              = crossChainTransferInput.Memo,
                FromChainId       = input.FromChainId,
                ParentChainHeight = input.ParentChainHeight,
                IssueChainId      = issueChainId
            });
            return(new Empty());
        }