• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

竹千代

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

去中心化钱包的交易设计

一、交易

 下图是MyEtherWallet里面的钱包应用和账户(一组公私钥)的关系图

  • 签名方法(WalletInterface/signTransaction):

带私钥的钱包应用的签名方法

import { Transaction } from '@ethereumjs/tx';
let tx = Transaction.fromTxData(txParams);
tx = tx.sign(this.privateKey);  // 这样签名的前提是,钱包应用有管理到私钥(比如助记词钱包、私钥钱包,但不包括walletConnect钱包)

无私钥方法(HybridWallet/HDWallet里面signTransaction,当isPrivKey为false的逻辑): 要用外部client的方法

  • nouce

要从链上获取最新的nouce值

const Web3 = require('web3');
const web3 = new Web3('https://mainnet.infura.io/v3/YOUR_INFURA_API_KEY');  // 钱包应用关联的infura节点
web3.eth.getTransactionCount(address);
  • gasPrice

一般会设置几种选项(经济型、常规、更快)

// 经济型: 从当前以太坊网络获取得到
gasPrice = await web3.eth.getGasPrice();
// 常规型
  if (gasPrice > LIMITER) {
    let initialValue = BigNumber(gasPrice).times(MED_MULTIPLIER);
    initialValue = initialValue.plus(MED_CONST);
    return BigNumber(initialValue).toFixed(0);
  }
  return BigNumber(gasPrice).times(1.25).toFixed(0);
// 更快型
  if (gasPrice > LIMITER) {
    let initialValue = BigNumber(gasPrice).times(FAST_MULTIPLIER);
    initialValue = initialValue.plus(FAST_CONST);

    return BigNumber(initialValue).toFixed(0);
  }
  return BigNumber(gasPrice).times(1.5).toFixed(0);

 

 

二、购买币

基本流程是:

  1. 前端从后台获取到全部的购买服务供应商信息, 包括名称、支持的法币列表、支持的法币->token购买列表;
  2. 用户在前端先选择要支付法币、要花费的金额、购入token存放地址;
  3. 确定后,转换到列表展示每个供应商可买入的token数量、费用等

要维护的供应商信息包括有

{
  0: {
    name: 'MOONPAY',
    // token和法币的汇率
    prices: [
      {
        crypto_currency: 'ETH', 
        fiat_currency: 'USD', 
        price: '3379.08322' 
      },
      ...
    ],
    // 支持的付款法币
    fiat_currencies: ['USD', 'EUR', ...],
    // 限额
    limits: [
      {
        fiat_currency: 'USD',
        limit: {
          min: 30,
          max: 5000
        }
      },
      ...
    ],
    // 法币间汇率
    conversion_rates: [
      {
        fiat_currency: 'USD',
        exchange_rate: 1
      },
      ...
    ]
  },
  1: {
    name: 'SIMPLEX',
    ......
  },
  ...
}

购买时具体需要信息(也要传给服务供应商的)包括:

      const buyObj = {
        cryptoToFiat: this.moonpayCryptoAmount,  // token数量
        selectedCryptoName: this.selectedCryptoName,  // token名
        plusFeeF: this.plusFeeF,    // 法币金额
        includesFeeText: this.includesFeeText,  // 费用
        networkFeeText: this.networkFeeText,
        dailyLimit: this.dailyLimit,
        monthlyLimit: this.monthlyLimit,
        fiatAmount: this.amount
      };
      this.$emit('success', [
        this.simplexQuote,  
        this.toAddress,  // 买入token存放地址
        buyObj,  
        1,
        this.selectedCurrency,  // token信息
        this.selectedFiat   // 法币信息
      ]);

 三、兑换

基本流程是:

  1. 后端维护能参与兑换的token列表; 
  2. 用户进入兑换页,前端查询,分类展示成当前链token,跨链token;
  3. 用户选择fromToken的类型、数量、toToken的类型,自动发请求到后台(供应商)查询后,以readonly形式展示toToken的数量
  4. 选择fromAddress和toAddress(数据来源于addressBookStore,额外应该有地址管理功能,可以增加保存自己的或者其他人的地址)
  5. 展示服务供应商列表供用户选择,包括具体信息(汇率、费用等)
  6. 用于选择交易提供商provider之后,自动调用供应商的getTrade方法,会得到1个trade结构数据,该结构数据用于构造tx。 返回trade结构里最重要的字段是data,它一个十六进制字符串,包含了调用智能合约方法的数据。
  7. 获取nouce,给交易签名signTransaction后,调用sendTransaction

第3步里兑换token数量查询依赖的数据

// 返回toToken的数量、汇率等
getQuote({
     fromContractAddress: fromAddress,
     toContractAddress: toAddress,
     amount: queryAmount.toFixed(fromT.decimals),
     chain: this.chain,   // 链地址
     excludeDexes: Object.values(MEWPClass.supportedDexes)
              .filter(dex => dex !== this.provider)
              .join(',')    // 要排除的交易所
}};

第6步里获取交易结构数据的请求参数

{
  address: fromAddress,
  recipient: toAddress,
  dex: this.provider,
  exchange: quote.exchange,
  platform: 'web',
  fromContractAddress: contactFromAddress,
  toContractAddress: contractToAddress,
  amount: queryAmount.toFixed(fromT.decimals),
  chain: this.chain
}

四、转账

五、NFT交易

基本流程:

  1. 构造NFT得交易数据结构
  2. 发送交易数据: 获取nouce、签名、发送
  send(to, token, gasPrice = undefined) {
    let raw;
    this.contract = new this.web3.eth.Contract(token.erc721 ? ABI : ERC1155ABI);
    if (token.contract.includes(configs.cryptoKittiesContract)) {
      raw = this.cryptoKittiesTransfer(to, token);
    } else if (token.erc721) {
      raw = this.safeTransferFrom(to, token);
    } else {
      raw = this.safeTransferFromRarible(to, token, 1);
    }
    raw.from = this.address;
    if (gasPrice !== undefined) raw.gasPrice = gasPrice;
    return this.web3.eth.sendTransaction(raw);
  }

  safeTransferFrom(to, token) {
    return {
      to: token.contract,
      // 交易data的内容是,调用合约的转移NFT的方法
      data: this.contract.methods
        .safeTransferFrom(this.address, to, token.token_id)
        .encodeABI()
    };
  }

 

五、跨链交易

posted on 2024-03-17 21:38  竹千代  阅读(60)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3