简述以太坊钱包如何跟交易所对接

作者: 优盾钱包 更新时间: 2020-06-10 15:06:45

优盾钱包(www.uduncloud.com)提供BTC_ETH_USDT_EOS_XRP等主流erc20代币对接交易所钱包充提币_转账支付归集_API/RPC的php/java开发接口。API快捷接入,多币种多地址钱包余额一键归集、私钥冷存储、多级复签、全终端支持。 点此立即试用



如果说2020年上半年币圈的焦点集中于比特币减半,那么下半年的赛道注意力则会被以太坊2.0所吸引。

 

现下公链项目中,仅趋于比特币庞大影响力之下的非以太坊莫属了。其它一些公链,大多借鉴比特币以及以太坊的公链项目进一步设计开发。

 

尽管近些年加密资产币种不断扩充,但依旧掩盖不住主流币种的风采。尤其是新起的交易所,可少不了以太坊等主流币种的交易对。交易所钱包作为虚拟币交易所系统的关键环节,承担着和各种不同区块链之间交互的重要任务,从而实现交易所用户地址生成、数字货币充值、转账、提现、代付以及余额、地址归集等多项功能。

 

由于区块链钱包开发的技术门槛较高,今天就开发者关注的的以太坊钱包如何对接交易所问题进行梳理与整合。

 

1、以太坊钱包开发和运行环境概述

 

在我们继续之前,首先要满足以下这些环境要求:

 

Docker: Docker已经成为新应用搭建的必备工具,它使得应用的构建、分享与部署都极其简单。

Docker Compose:我们使用Docker Compose来管理所有的服务,以便轻松地进行扩展。

 

另外的需求能够用Docker镜像来满足,我们不需要安装其他任何东西了,只需要写一个简单的Docker Compos配置文档 —— docker-compose.yml:




在此基础上只需运行docker-compose up -d便能够快速启动服务,这个命令会自动从Docker中心下载需要的镜像,随即启动。接下来一起包含了哪些服务。


1.1 Ganache-cli

 

如果没有接入以太坊区块链的节点,我们的钱包服务就不会有什么用。在开发期我们不需要下载整个以太坊区块链,因此只要使用Ganache仿真器即可。使用Ganache的好处是开发效率高,因为出块极快。不过在生产环境中就需要使用像Geth这样的节点软件来接入以太坊主网了。


1.2 Redis

 

需要数据库来保存创建的地址,并且监听这些地址相关的交易。Redis作为一个出色的内存键/值数据库,使用此次演示的应用场景。

 

在这个教程中,可以将Redis数据库来保存我们为钱包地址生成的私钥,值得一提的是,在生产服务器上应当使用更加安全的硬件设施来保护这些私钥。


1.3 Kafka/Zookeeper

 

Apache Kafka可谓是交易所架构中核心角色,它负责接收来自全部服务的消息,并将它们分发给订阅这些消息的节点。


针对以太坊钱包服务项目来讲,大家将应用下列这种主题开展通信:

 

command

address.created

transaction

errors


服务器 Apache Kafka 可以独立扩展,为钱包服务提供一个分布式消息处理集群。 


2、以太坊钱包开发语言选择

 

就笔者自身来说,相对来说更偏爱于Elixir,毕竟它可以用来写出比较靠谱的分布式应用,并且编写的代码在易理解和易维护性能方面占有优势。如果恰巧考虑到以太坊的生态,Elixir的优势就不复存在了。

 

针对以太坊开发设计来讲,建议可以应用Node.js/Javascript。毕竟有许多组件可以直接使用。因此,此次的以太坊钱包服务就是利用Node.js来进行开发。


3、 搭建初始开发环境

 

第一步运行npm init命令来建立默认设置的node包:

 

~/exchange-hubwiz/eth-wallet$ npm init

 

    

接着我们需要对以太坊钱包服务要使用到的node依赖包进行添加,详细执行命令有下面这些:

 

~/exhcange-hubwiz/eth-wallet$ npm install --save web3 redis kafka-node ethereumjs-tx bluebird

 

 

前3个依赖包的意义相对容易了解些:

 

web3:根据websocket连接到Ganache或别的以太坊节点

redis:连接到 Redis服务器便于储存或是获取数据信息

kafka-node:接入Zookeeper,提取Kafka访问端结点,对Kafka消息进行生产或消费

 

最终的2个依赖包有利于使我们的代码更加便于掌握,而且能够充分运用到async/await的异步编程模式的优点。


其次,我们将把这些node包连接Redis、以太坊和Kafka服务器。

4、连接服务器

4.1 连接Redis服务器

 

连接Redis操作相对容易,建立一个redis.js文件,然后编写如下代码:




4.2 连接以太坊节点

 

假如你已经觉得连接Redis非常简单了,那么在使用web3连接以太坊节点时,容易程度会让你大吃一惊。

建立一个ethereum.js,随即编写代码如下

 

const config = require('../../config')

const Web3 = require('web3')

module.exports = new Web3(config.uri)

 

 

4.3 连接Kafka服务器

 

Kafka,有必要从队列中获取消息进行消费,或者生产消息存进队列。所以,咱们还需要继续进行某些相关的配置。

 

建立一个新的文件query.js,编写如下的代码:



5、以太坊钱包服务


从现在起,咱们进入了以太坊钱包服务的核心特性开发阶段。

5.1 创建新的以太坊账户

用户需要由交易所和支付网关生成新的没有用过的以太坊地址,便于其随时随地向服务充值,或者是为某产品付费。怎样由代码进行实现的呢?

第一步,建立一个commands.js,在其中我们订阅队列中的消息。主要可以概述为以下几点:

连接到command主题

监听新的create_account命令

当收到新的create_account命令时

创建新的密钥对并存入密码库

生成account_created消息

并发送到队列的account_created主题

代码如下:

const web3 = require("./ethereum")

const redis = require('./redis')

const queue = require('./queue')

 

/**

 * Listen to new commands from the queue

 */

async function listen_to_commands() {

  const queue_consumer = queue.consumer('eth.wallet.manager.commands', ['command'])

  // process messages

  queue_consumer.on('message', async function (topic_message) {

    try {

      const message = JSON.parse(topic_message.value)

      // create the new address with some reply metadata to match the response to the request

      const resp = await create_address(message.meta)

      // if successful then post the response to the queue

      if (resp) {

        await queue_producer.send('address.created', [resp])

      }

    } catch (err) {

      // in case something goes wrong catch the error and send it back in the 'errors' topic

      console.error(topic_message, err)

      queue_producer.send('errors', [{type: 'command', request: topic_message, error_code: err.code, error_message: err.message, error_stack: err.stack}])

    }

  })

  return queue_consumer

}

 

/**

 * Create a new ethereum address and return the address

 */

async function create_account(meta = {}) {

  // generate the address

  const account = await web3.eth.accounts.create()

  

  // disable checksum when storing the address

  const address = account.address.toLowerCase()

  

  // save the public address in Redis without any transactions received yet

  await redis.setAsync(`eth:address:public:${address}`, JSON.stringify({}))

  

  // Store the private key in a vault.

  // For demo purposes we use the same Redis instance, but this should be changed in production

  await redis.setAsync(`eth:address:private:${address}`, account.privateKey)

  

  return Object.assign({}, meta, {address: account.address})

}

 

module.exports.listen_to_commands = listen_to_commands


5.2 处理新交易

 

值得注意的是,当咱们在创建的地址收到用户充值后理应收到通知信息。因此,以太坊的web3客户端就提供了newBlockHeaders订阅机制。另外,假如钱包服务出现偶然宕机的情况,那么服务就会错过在宕机期间生产的区块,所以咱们务必要检查钱包是不是已经对网络的最新区块进行了同步。

 

建立sync_blocks.js文件,编写如下代码:




在上面的代码中,咱们从以太坊钱包服务之前处理的最新区块开始,一直同步至区块链的当前最新区块。只要我们同步到最新区块,程序就会开始订阅新区块事件。对于每一个区块,我们都执行如下的回调函数以处理区块头以及区块中的交易列表:

 

onTransactions

onBlock

 

一般情况下涵盖了一下几个处理步骤:

 

对新区块进行监听,提取区块中的所有交易

对跟以太坊钱包地址无关的交易进行过滤

把所有相关的交易都发至队列

把以太坊钱包地址上的资金归集到安全的存储

更新已处理的区块编号

 

编写代码如下:

const web3 = require("web3")

const redis = require('./redis')

const queue = require('./queue')

const sync_blocks = require('./sync_blocks')

 

/**

 * Start syncing blocks and listen for new transactions on the blockchain

 */

async function start_syncing_blocks() {

  // start from the last block number processed or 0 (you can use the current block before deploying for the first time)

  let last_block_number = await redis.getAsync('eth:last-block')

  last_block_number = last_block_number || 0

  // start syncing blocks

  sync_blocks(last_block_number, {

    // for every new block update the latest block value in redis

    onBlock: update_block_head,

    // for new transactions check each transaction and see if it's new

    onTransactions: async (transactions) => {

      for (let i in transactions) {

        await process_transaction(transactions[i])

      }

    }

  })

}

 

// save the lastest block on redis

async function update_block_head(head) {

  return await redis.setAsync('eth:last-block', head)

}

 

// process a new transaction

async function process_transaction(transaction) {

  const address = transaction.to.toLowerCase()

  const amount_in_ether = web3.utils.fromWei(transaction.value)

 

  // check if the receiving address has been generated by our wallet

  const watched_address = await redis.existsAsync(`eth:address:public:${address}`)

  if (watched_address !== 1) {

    return false

  }

 

  // then check if it's a new transaction that should be taken into account

  const transaction_exists = await redis.existsAsync(`eth:address:public:${address}`)

  if (transaction_exists === 1) {

    return false

  }

 

  // update the list of transactions for that address

  const data = await redis.getAsync(`eth:address:public:${address}`)

  let addr_data = JSON.parse(data)

  addr_data[transaction.hash] = {

    value: amount_in_ether

  }

 

  await redis.setAsync(`eth:address:public:${address}`, JSON.stringify(addr_data))

  await redis.setAsync(`eth:transaction:${transaction.hash}`, transaction)

  

  // move funds to the cold wallet address

  // const cold_txid = await move_to_cold_storage(address, amount_in_ether)

  

  // send notification to the kafka server

  await queue_producer.send('transaction', [{

    txid: transaction.hash,

    value: amount_in_ether,

    to: transaction.to,

    from: transaction.from,

    //cold_txid: cold_txid,

  }])

 

  return true

}

 

module.exports = start_syncing_blocks


从上述五个方面,我们展示了以太坊钱包如何跟交易所对接的几个步骤,另外在对接以太坊钱包时可对错误处理的增添、对命令类型的增添、交易签名和交易广播以及部署合约进行优化,从而使程序更加完善,更符合用户的需求。


值得关注的是,以太坊系钱包,一般只能对接以太坊系币种,随着数字货币币种的不断扩展,用优盾钱包这类多币种支持的交易所钱包系统更为方便。


优盾钱包,是目前国内最好用的企业钱包开放平台。API一键对接,支持当下多数主流币种、多资产多地址统一管理、用户提币初审+复核安全模式、系统代付自动放币、多员工多钱包多权限一键分配、资产交易查询、资金流动消息提醒等多种功能。

 

防黑客技术上:

API接口信息访问验签、基于HTTPS安全传输,拒绝被监听

私钥不上传、不触网,并通过二次加密托管在客户端侧

钱包绑定电脑MAC地址,拒绝非认证设备访问

冷热钱包分离,大额资产用冷钱包离线保存


防内鬼技术上:

员工操作权限管理员一键设置

员工操作记录管理员一键查询

员工只接触管理独立小额子钱包

超额转出交易需管理员复核

员工在非公司指定电脑设备登录优盾账号需管理员同意


便捷接入:

①免节点同步;

②标准接口;

③详细接口文档;

④接入DEMO;

⑤7*24小时技术支持。


相关文章:

1.区块链技术下,虚拟币多币种钱包系统如何部署?

2.交易所老板最“怕”遇到的销售

3.Bitcoin钱包开发之地址生成教程

4.细数交易所被盗史 如何避免交易所被盗黑天鹅