Published in
白纸黑字
李安
@1051445
一文讲清如何接入 MVM
MVM Mixin Web3 开发
2022-12-18 05:53
Words count: 5512
结合 Quill 的实践,从开发者的角度聊一下如何接入 MVM。

MVM 是一个跨链的智能合约平台,也是连接 Mixin 生态和其他所有主链的桥梁。Quill 是一个支持加密货币的付费阅读的写作平台,是目前应用 MVM 最典型的例子。

本文将结合 Quill 的具体实践,聊聊如何让一个新项目通过接入 MVM,承接 Web3 的需求。

在 Web3 方面 Quill 的主要需求包括

  • 用户可以用任意主流钱包登录
  • 用户可以用任意主流加密货币进行小额支付购买文章
  • 用户可以高频、小额地接收加密货币的收益转账

下面详细讲如何利用 MVM 来方便快捷地实现以上需求。

注册 Mixin 机器人

如果你的项目原本并非 Mixin 应用,需要先在 Mixin 开发者平台注册一个 Mixin 机器人,这可以用作很多 Mixin API 的调用主体,也可以作为项目的收款钱包。

以太坊钱包登录

利用以太坊钱包登录的流程跟一般 Web3 项目并无二致,最简单的方法就是后台生成一个随机数 nonce,引导用户在前端用钱包(例如 MetaMask )签名后,再将 address 和签名一同发到后端进行签名验证,验证通过即登录成功。

注册 MVM 跨链桥代理帐号

当用户登录成功后,即可帮用户在 MVM 的跨链桥上进行注册,获得一个代理 Mixin 帐号。为了方便讲解,这里假设用户的以太坊地址是 0x7bD230817b9314239A07049AD3240bEA0Ee35396 。

注意实际请求的时候换成用户的以太坊地址。

curl -H 'Content-Type: application/json' https://bridge.mvm.dev/users \
    -d '{"public_key":"0x7bD230817b9314239A07049AD3240bEA0Ee35396"}'

得到的返回结果是

{
  "user": {
    "contract": "",
    "created_at": "2022-08-09T11:36:17.025157427Z",
    "full_name": "0x7bD230817b9314239A07049AD3240bEA0Ee35396",
    "key": {
      "client_id": "53277182-0058-3268-85c3-aa67d91bbcb3",
      "private_key": "c1IqlzIyTR5oF1mcviU9QxeFQZM-Luyw2WA9vY7_Lk80nT5Vju4G4sKo7-_q8_TOrPN4zXflp5-0_4x0bvLPQQ",
      "session_id": "c309ce8a-69ba-404c-8fe9-7727b7afdc6d"
    },
    "session_id": "c309ce8a-69ba-404c-8fe9-7727b7afdc6d",
    "user_id": "53277182-0058-3268-85c3-aa67d91bbcb3"
  }
}

请求结果里面的 user_id (即 53277182-0058-3268-85c3-aa67d91bbcb3 )为该用户唯一对应的代理 Mixin 帐号,用户任意资产的转入都可以通过这个代理帐号来完成。

而 key 里面的 client_id、 private_key 和 session_id 则是代理帐号的部分私钥信息,可以用来调用 Mixin API 完成必要的查询操作。

不需要担心代理帐号因为暴露了私钥信息,导致资产不安全。Mixin 帐号的资产转账需要 keystore + 六位数字 PIN 码共同完成签名验证,上面的私钥信息只足够完成 Mixin API 的查询需要,无法完成资产转移操作。

用户充值

拥有了代理 Mixin 帐号,意味着你的用户虽然来自其他任意钱包(譬如 MetaMask 或者 ImToken),但此刻拥有了一个 Mixin 钱包。

在支付之前,需要先引导用户充值,Mixin 支持超过 40 条主链,基本上所有资产都能支持。充值的过程就是给用户的代理 Mixin 帐号充值,是一个典型的 Mixin 充值过程。

以充值 ETH 为例,ETH 在 Mixin 里的资产 ID 是 43d61dcd-e413-450d-80b8-101d5e903357,利用 Mixin API 就可以查到用户 ETH 充值地址。

curl -i -X GET -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" https://api.mixin.one/assets/43d61dcd-e413-450d-80b8-101d5e903357

TOKEN 需要按照 Mixin 文档利用用户的私钥信息生成,目前 Mixin 社区已经提供了各种主流语言的 SDK,开发者可以直接使用。

上述请求的返回结果里,有个 deposit_entries ,就是该资产的充值地址。

{
  "type": "asset",
  "asset_id": "43d61dcd-e413-450d-80b8-101d5e903357",
  "chain_id": "43d61dcd-e413-450d-80b8-101d5e903357",
  "fee_asset_id": "43d61dcd-e413-450d-80b8-101d5e903357",
  "symbol": "ETH",
  "name": "Ether",
  "icon_url": "https://mixin-images.zeromesh.net/zVDjOxNTQvVsA8h2B4ZVxuHoCF3DJszufYKWpd9duXUSbSapoZadC7_13cnWBqg0EmwmRcKGbJaUpA8wFfpgZA=s128",
  "balance": "0",
  "deposit_entries": [
    {
      "destination": "0x62F6BAd43aEd1f285f0a9C71Fb20B2aaf0eb7c0F",
      "tag": "",
      "properties": ""
    }
  ],
  "destination": "0x62F6BAd43aEd1f285f0a9C71Fb20B2aaf0eb7c0F",
  "tag": "",
  "price_btc": "0.07045842",
  "price_usd": "1174.68",
  "change_btc": "-0.03513549488278948",
  "change_usd": "-0.07620440711555702",
  "asset_key": "0x0000000000000000000000000000000000000000",
  "mixin_id": "8dd50817c082cdcdd6f167514928767a4b52426997bd6d4930eca101c5ff8a27",
  "reserve": "0",
  "confirmations": 36,
  "capitalization": 0,
  "liquidity": "0"
}

例如这个例子里,在以太坊主网向 0x62F6BAd43aEd1f285f0a9C71Fb20B2aaf0eb7c0F 地址转账 ETH,即可以充值到该用户的 MVM 账户上。充值进度可以则用这个 API 来查询。资产到帐之后,用 MVM 的浏览器可以查到用户的 MVM 资产余额。

在业务上,也可以选择直接把用户引导至 MVM 官方的跨链桥完成充值。

用户支付

当用户账户里有资产,就可以发起支付了。

注意,这里说的支付,是指 MVM 用户向任意 Mixin 钱包发起的支付。具体到 Quill 的场景,就是MVM 用户购买文章时,向 Quill 的 Mixin 机器人钱包发起支付。如果是 MVM 用户相互转账,或者向 MVM 其他合约转账,情况则与以太坊一样,正常调用合约转账即可。

支付前的准备

在正式调用支付前,必须确认用户钱包已经切换至 MVM 网络,MVM 网络参数可以参考这里。

Network name:Mixin Virtual Machine

RPC link:https://geth.mvm.dev

ChainID:73927

Symbol:ETH

当新用户在跨链桥注册之后,不仅会得到一个 Mixin 代理帐号,在 MVM 网络中,还会自动生成一个对应的合约地址,该合约地址与 Mixin 代理帐号相对应,这里称之为代理合约 。代理合约的地址可以用这个 API 获取

GET https://api.mvm.dev/user_contract?user=$USER_ID

代理合约地址也可以通过调用 Registry 合约的方式获取,详情可以参考这里的代码。

用户支付分为三种情况,下面分开一一讲解。

以下讲解重在理清支付的流程,完整代码片段可以参考 Quill 的源码,实际使用时也可以直接使用 Mixin 的 SDK 。

支付原生代币

MVM 原生代币是 ETH,所有合约调用支付的 Gas 费也是 ETH。

当用户支付 ETH 时,步骤如下

  1. 获取用户的代理合约地址;
  2. 生成收款人信息的 extra;
  3. 调用跨链桥合约的 release 方法。

本例中,从 API

https://api.mvm.dev/user_contract?user=53277182-0058-3268-85c3-aa67d91bbcb3

可以得到用户的代理合约地址为 0x346f9eD85A090e3afEFC5c1959B0c9E53Eac7cdC 。

然后需要将收款人信息和你想要携带的 memo 信息按照一定格式编译成一个 extra 字符串,具体代码可以参考

fetchExtra(receivers: string[], threshold: number, memo: string): string {
  const action = {
    receivers,
    threshold,
    extra: memo,
  };
  const extra =
    RegistryID.replaceAll('-', '') +
    StorageAddress.slice(2).toLowerCase() +
    this.web3.utils.sha3(JSON.stringify(action)).slice(2) +
    JSON.stringify(action)
      .split('')
      .map((v) => {
         return v.charCodeAt(0).toString(16);
      }).join('');

  return extra;
}

解释一下里面的关键参数。

receivers + threshold 共同指定了收款人地址。

譬如如果是转给 Quill,Quill 的机器人钱包地址是 6d8fd25a-1eb1-4afb-b2a6-d34991959b76 ,那么

receivers = [ "6d8fd25a-1eb1-4afb-b2a6-d34991959b76" ];
threshold = 1;

如果是向 4swap 转账,因为 4swap 是一个 MTG,所以实际上是给一个 3/5 的多签地址转账,根据 4swap 的文档可知

receivers = [
  "a753e0eb-3010-4c4a-a7b2-a7bda4063f62",
  "099627f8-4031-42e3-a846-006ee598c56e",
  "aefbfd62-727d-4424-89db-ae41f75d2e04",
  "d68ca71f-0e2c-458a-bb9c-1d6c2eed2497",
  "e4bc0740-f8fe-418c-ae1b-32d9926f5863"
];
threhold = 3;

memo 是随转账携带的自定义文本信息,通常用来标明转账的用途,以便收款人收款后进行相应的操作。例如 Quill 的 memo 格式比较简单,下面是购买某篇文章的 memo 例子。

memo = Base64.urlsafe_encode64({ t: 'BUY', a: uuid }.to_json)

RegistryID 和 StorageAddress 都是常量,可以从跨链桥的 API 获取,一般不会有变动,本地存好就行。

准备好代理合约地址和 extra 之后,就可以正式调用合约了。

下面是合约调用的代码片段。

const BridgeContract = new this.web3.eth.Contract(BridgeABI, BridgeAddress);
BridgeContract.methods
  .release(contract, `0x${extra}`)
  .send({ from: this.account, value: payAmount.toString() })
  .on('transactionHash', success)
  .on('error', fail);

其中 BridageABI 和 BridgeAddress 都可以从跨链桥的 API 获取。

contract 是用户的代理合约地址,在本例中即 0x346f9eD85A090e3afEFC5c1959B0c9E53Eac7cdC 。

this.account 是用户的实际以太坊钱包地址,在本例中即 0x7bD230817b9314239A07049AD3240bEA0Ee35396。

payAmount 是转账的数量,注意原生代币的精度是 18,如果转账 0.1 ETH,实际输入应该是 0.1 × 1e18 。

一切顺利的话,就会唤起用户的钱包(譬如 MetaMask),进行签名,完成支付。

MVM 的 Gas 费用很低,可以设置 gasPrice = 10000000,实际调用时,每笔转账的 Gas 费目前一般是 0.00000403 ETH 左右。

支付其他代币

除了 MVM 原生代币 ETH,其余资产在 MVM 网络中都是 ERC20 合约代币,支付此类资产的流程如下

  1. 获取用户的代理合约地址;
  2. 生成收款人信息的 extra;
  3. 获取转账代币的合约地址;
  4. 调用代币合约的 transferWithExtra 方法。

前两步跟前文一样,不再赘述。

Mixin 中每种资产在 MVM 网络中都有对应的合约地址,利用 Mixin 资产的 asset_id 调用 Registry 合约可以查询得到,代码片段可以参考这里。

譬如转账 BTC,调用合约查询得到 BTC 在 MVM 中的合约地址是 0x0e42Ae5649B3a67842AF0F3fC21d09d9b850A694 。

然后就可以调用合约发起支付了,代码片段如下

const IERC20 = new this.web3.eth.Contract(ERC20ABI, assetContractAddress);
IERC20.methods
  .transferWithExtra(contract, payAmount.toString(), `0x${extra}`)
  .send({ from: this.account })
  .on('transactionHash', success)
  .on('error', fail);

这里的 ERC20ABI 是资产的合约 ABI,可以从合约地址获取。

assetContractAddress 就是资产的合约地址,BTC 就是0x0e42Ae5649B3a67842AF0F3fC21d09d9b850A694。

payAmount 是转账的数量,注意这里的精度是 8,跟 Mixin 资产精度一致,如果转账 0.1 BTC,实际输入应该是 0.1 × 1e8 。

一切顺利的话,就会唤起用户的钱包(譬如 MetaMask),进行签名,完成支付。

转账 NFT

将 NFT 从 MVM 用户转到其他 Mixin 帐号,流程跟上述代币转账差不多,只是具体调用合约不一样,这里不再详述,可以参考 Quill 源码中的代码片段。

更简单的支付方案

在 Quill 的实践中发现,新用户注册完成之后,在实际购买行为之前,先要完成网络切换和资产充值这两步,对新用户的门槛比较高。

MixPay 提供了多渠道、多币种支付,然后结算至 Mixin 钱包的支付方案,非常适合 Quill 的场景。所以 Quill 在 MVM 新用户支付时,是直接引导其至 MixPay 的 checkout 页完成支付。MixPay 的具体使用可以参考 MixPay 的文档。

使用 MixPay 时,值得注意的是,项目最后收到的转账并非直接来自用户的帐号,而是来自 MixPay 的帐号,因而需要用其他方式判定实际的付款人。可以采用在 memo 中携带实际付款人信息的方式。

用户收款

根据 Quill 的规则,每次文章被购买,都需要向文章作者和文章的早期读者支付收益。譬如文章被购买 1000 次,将会发起超过 50 万笔转账。

幸运的是,从 Mixin 钱包向 MVM 用户转账时,不需要支付 Gas 费调用合约,而是直接向其代理 Mixin 帐号发起 Mixin 转账即可。

例如本例中,用户的代理 Mixin 帐号是 53277182-0058-3268-85c3-aa67d91bbcb3 ,利用 Mixin 机器人调用 Mixin API 直接向其发起转账即可,快速免费。

用户提现

目前有两个开源项目支持 MVM 用户提现的,分别是 Mixin 官方的 MVM Bridge 和来自社区开发者 zed-wong 的 MVG。

如有需要可以参考这两个项目的代码自行实现。或者在业务上,如果用户需要将 MVM 内的资产提现至其他钱包,可以引导用户到任意一个跨链桥上完成。

关于提现,还需要重点提醒一下用户,不能通过 MetaMask 直接跨链提现,必须通过跨链桥调用相关的提现合约才能成功。否则可能丢失资产。

其他补充说明

MVM 实际上由两个部分组成

  • 由 7 个节点组成的 MTG,即多签组,负责管理所有 MVM 用户的资产;
  • 由 7 个节点组成的 EVM 网络,负责执行 MVM 网络的智能合约。

MVM 相关代码全部开源,7 个节点来自 Mixin 社区长期耕耘的项目方,安全可靠。另外 MTG 节点数量也并非固定不变,后续是可以根据需要增加的。

上述的代理 Mixin 帐号,部分私钥信息是公开的,但是最重要的六位数字 PIN 码是由 MTG 的节点通过 TIP 协议共同管理的,所以资产是安全的。

在 MVM 用户充值和收款时,当代理 Mixin 帐号被检测到有新入账资产,资产并不会在该帐号中留存,MTG 会即时将该资产转入到 MTG 的多签钱包托管,同时在 MVM 网络中铸造相应的 ERC20 资产,转入对应的 MVM 用户帐号。

在 MVM 用户付款时,当合约被调用成功,MTG 会把相应的资产转出到该用户的代理 Mixin 帐号,然后由代理帐号再把资产转账给相应的收款人。

对于用户来说,依然是掌握着自己原本的私钥,使用着自己熟悉的钱包,通过 MVM,可以同时管理一个跨链的 Mixin 钱包,从而连接整个 Mixin 生态。

参考文档

  • MVM 开发文档:https://mvm.dev/
  • MVM 跨链桥重要合约地址:https://bridge.mvm.dev/
  • Mixin 开发者文档:https://developers.mixin.one/docs/api-overview
  • Mixin 及 MVM 相关的 JS SDK:https://github.com/MixinNetwork/bot-api-nodejs-client
  • MVM 官方跨链桥项目:https://bridge.mvm.app/
  • MVM Bridge 项目源码:https://github.com/MixinNetwork/bridge.mvm.app
  • 跨链桥项目 MVG:https://mvg.finance/
  • Quill 项目源码:https://github.com/baizhiheizi/quill
  • MixPay 开发者文档:https://mixpay.me/developers

最后

本文所有内容都是来自我个人的实践和理解,如有错漏,敬请斧正。

如果有任何其他疑问,也欢迎留言讨论。

Trident NFT
2bf6ed85-27d7-4290-a24a-48fcb1319226
Arweave TX
BdiY8h7XdoyWr9jwT9fQ7Q04xZy1Ww0Jq4wLq--NMq4
Content Digest
99503cc2971cc2908e26e9616dae40f0574f0606670d67a62861206a511c73cd
Reward
11 : 0
0 times bought, 5 times reward
0.0
Price(BTC)
5
Paid Times
19.5807
Revenue(USD)
0.0
My Share(%)
Comments
Subscribe
李安
@1051445
Subscribing: 31 Subscribers: 446
Founder of Quill
Subscribe
白纸黑字 (BZHZ)
大概是 2010 年左右,我经常写的博客平台关停了。于是我开始自建博客,取了个名字,叫“白纸黑字”。因为我始终相信互联网是有记忆的,在网络留下的所有文字都将不可磨灭。秉着这个“心理负担”,在网上发表任何文字前都多了一份敬畏之心,告诫自己,留下的所有文字都至少要,**真诚**。 这个合辑没有固定的主题,想起来啥就写点啥。**没有知识,没有干货**,只是一些非常个人的分享。尽量保证周更,至少更新一年。 合辑内的所有文章也供单独购买,单独售卖所得的 40% 收益将会分给本合辑所有购买者。 购买合辑之后可以铸造一个 NFT 出来,凭 NFT 可以加入我的个人群(Mixin 搜索机器人 7000101617)。 购买后如果你觉得不值,可以将 NFT 在 Trident 上出售给其他有兴趣的读者。出售 NFT 后将无法阅读合辑的文章,但是可以继续享有合辑的收益权。
40.0%
Collection Revenue
18
Subscribers
Subscribe
Related Posts
Mixin 的灵魂 macOS系统多开Google Chrome浏览器 Mixin 的 Observer 是个 MAO Mixin Safe 上线规划 Mixin : A Decentralized Web3 Platform Built to Scale (Part 2)
Rules Stats Help Github Twitter Discord
李安
@1051445
Subscribing: 31 Subscribers: 446
Founder of Quill
Subscribe
白纸黑字 (BZHZ)
大概是 2010 年左右,我经常写的博客平台关停了。于是我开始自建博客,取了个名字,叫“白纸黑字”。因为我始终相信互联网是有记忆的,在网络留下的所有文字都将不可磨灭。秉着这个“心理负担”,在网上发表任何文字前都多了一份敬畏之心,告诫自己,留下的所有文字都至少要,**真诚**。 这个合辑没有固定的主题,想起来啥就写点啥。**没有知识,没有干货**,只是一些非常个人的分享。尽量保证周更,至少更新一年。 合辑内的所有文章也供单独购买,单独售卖所得的 40% 收益将会分给本合辑所有购买者。 购买合辑之后可以铸造一个 NFT 出来,凭 NFT 可以加入我的个人群(Mixin 搜索机器人 7000101617)。 购买后如果你觉得不值,可以将 NFT 在 Trident 上出售给其他有兴趣的读者。出售 NFT 后将无法阅读合辑的文章,但是可以继续享有合辑的收益权。
40.0%
Collection Revenue
18
Subscribers
Subscribe
Related Posts
Mixin 的灵魂 macOS系统多开Google Chrome浏览器 Mixin 的 Observer 是个 MAO Mixin Safe 上线规划 Mixin : A Decentralized Web3 Platform Built to Scale (Part 2)
Rules Stats Help Github Twitter Discord