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()); }
/// <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()); }