-
Notifications
You must be signed in to change notification settings - Fork 10
交易所对接指南(中文)
这篇文档主要描述了交易所如何一步一步完成和VEE(VVV)区块链的对接交互。
For English version Instructions for Exchanges, please click here
目前阶段,标准硬件配置是2核CPU,16G内存,和1TB高速硬盘的独立主机。
推荐配置是i3 large型号的亚马逊云主机(AWS)
可以是所有 Java 1.8 和 Python 可以运行的任何操作系统 (包括 Ubuntu, CentOS, MacOS, Windows 等)。
我们推荐的操作系统是 Ubuntu 16.04 LTS (或其更高版本)。
这篇文档我们以Ubuntu 16.04为例进行介绍。
首先我们更新软件包管理器
$ sudo apt-get update
在主机上安装Java 1.8
$ sudo apt-get install openjdk-8-jdk
检查Java版本(需要删除低版本的Java)
$ java -version
openjdk version "1.8.0_181"
OpenJDK Runtime Environment (build 1.8.0_181-8u181-b13-0ubuntu0.16.04.1-b13)
OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)
如果您选择编译我们的源码搭建全节点,需要安装Scala编译工具(SBT)
$ echo "deb https://dl.bintray.com/sbt/debian /" | sudo tee -a /etc/apt/sources.list.d/sbt.list
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 2EE0EA64E40A89B84B2DF73499E82A75642AC823
$ sudo apt-get update
$ sudo apt-get install sbt
如果没有Unzip和Git,请在主机上安装这些软件
$ sudo apt-get install unzip
$ sudo apt-get install git-core
有两种方法准备全节点程序,请任意选择一个方法。
从GitHub上下载源代码
$ git clone https://github.com/excelsia/vee.git
$ cd vee
用SBT编译源代码。如果您希望编译测试网(Testnet)的VEE全节点,请运行
# Compile TestNet VEE node
$ sbt -Dnetwork=testnet packageAll
如果您希望编译主网(Mainnet)的VEE全节点,请运行
# Compile MainNet VEE node
$ sbt packageAll
编译好的文件将会放在target/vee-all-[version].jar这个位置。复制到你自己的工作目录,例如:
$ mkdir ../vee-node
$ cp target/vee-all-*.jar ../vee-node/
$ cd ../vee-node
如果您不想编译源代码,您也可以选择在 https://github.com/excelsia/vee/releases 下载最新的JAR文件。
将vee-all-[version].jar保存到您的工作目录。
设置您的配置文件
# VEE node settings
vee {
# Path Settings
directory = <block data folder path>
# Application logging level. Could be DEBUG | INFO | WARN | ERROR. Default value is INFO.
logging-level = INFO
# P2P Network settings
network {
known-peers = ["<peer ip>:<peer port>"]
black-list-residence-time = 30s
peers-broadcast-interval = 5s
connection-timeout = 30s
# Network address
# Node name to send during handshake. Comment this string out to set random node name.
# node-name = "My MAINNET node"
}
# Wallet settings
wallet {
# Password to protect wallet file
password = ""
# Wallet seed as BASE58 string
# seed = ""
}
# Blockchain settings
blockchain.type = TESTNET # Should be TESTNET or MAINNET
# Matcher settings
matcher.enable = no
# Minter settings
miner {
enable = yes
offline = no
quorum = 1
generation-delay = 1s
interval-after-last-block-then-generation-is-allowed = 120h
tf-like-scheduling = no
# Left to empty as default to minter address
reward-address = ""
}
# Node's REST API settings
rest-api {
# Enable/disable node's REST API
enable = yes
# Hash of API key string
api-key-hash = "Fo8fR7J1gB3k2WoaE6gYKMwgWfoh9EtZtXAMBxYYCJWG"
}
checkpoints.public-key = "A9MX22tXpNdTTx5wBf3CunZz299c1nnca6kH3MzL312L"
}
-
directory应该设为您自己的工作目录
-
known-peers 这项最好填3个或以上的已知节点。您可以在VEE explorer查询这些已知节点。现在正在运行的一些节点有:
# 测试网 known-peers = ["18.179.34.202:9923", "13.250.53.12:9923", "18.188.219.229:9923"] # 主网 (欲知更多节点请和我们联系) known-peers = ["54.147.255.148:9921"]
-
blockchain.type 应该填 TESTNET 或 MAINNET.
-
为安全起见,api-key-hash这项最好设置成您自己的哈希值。您可以通过这个命令算出您的api密钥的哈希值:
curl -X POST -d '<输入任意字符作为您的api密钥>' 'https://wallettestnet.vee.tech/api/utils/hash/secure'
-
最后,我们命名并保存配置文件,例如命名为"vee.conf"。
我们建立一个screen并运行
$ screen -S vee-node
$ sudo java -jar vee*.jar vee.conf
如果需要退出screen,可以在键盘上按 Ctrl + A + D
。
如果需要再次进入screen看状态,可以运行
$ screen -x vee-node
安全提醒:所有的全节点都提供RESTful API进行交互,RESTful API会用到9922端口。安全起见,我们建议交易所修改防火墙规则,不要将9922端口开放到公网,仅内网使用。
以下是调用API的几种方法。
如果您使用python对接,我们强烈建议您使用pyvee项目完成交互对接。详情请参阅这里。
您可以打开浏览器输入http://<全节点ip>:9922
使用Swagger,在这里也可以查阅所有可以使用的API。
如果没有安装curl,请安装这个程序,用于发送HTTP请求。
$ sudo apt-get install curl
您可以用以下方法测试连接
$ curl -X GET --header 'Accept: application/json' 'http://<节点ip>:9922/blocks/height'
如果请求成功,您将收到类似这样的回应:
{
"height": 2400326
}
发送HTTP POST请求调用/addresses这个API
$ curl -X POST --header 'Accept: application/json' --header 'api_key: <节点api密钥>' 'http://<节点 ip>:9922/addresses'
如果创建成功,您将会收到一个包含钱包地址的回应:
{
"address": "AUBBmrf5cuBf9XrSaX98mxWmcNBwULqQhQK"
}
创建的钱包数据都会保存在<block data folder path>/wallet/wallet.dat
这个文件里,这个文件最好定期进行备份。
我们也可以根据seed还原钱包,如果查找钱包的seed,可以通过发送HTTP GET调用/addresses/seed/{address} 这个API找到seed(需要带入API密钥),例如
$ curl -X GET --header 'Accept: application/json' --header 'api_key: <节点api密钥>' 'http://<节点ip>:9922/addresses/seed/AU9KCwJm6mG9YxSb3LdjVi6LDwRGey1knfy'
如果成功将返回类似这样的结果:
{
"address": "AU9KCwJm6mG9YxSb3LdjVi6LDwRGey1knfy",
"seed": "GY7T8WpppuficZJs9CnEuntLkk4vXw7qkZ1SMtZ3qAas"
}
当您知道了seed,您可以通过 wallet-generator 这个项目来还原钱包地址。
使用 HTTP GET 调用 /addresses API 获取节点内的全部钱包:
$ curl -X GET 'http://<节点ip>:9922/addresses'
如果成功将返回类似结果:
[
"ATy98tPdobDBKA35n5CJed6u3AmxKLT3TTV",
"ATys7iafCN4xHz9bJyKm4JNfKpk9f1uBBXT",
"AU1TFgjs3g1NMkXW5CGTGj96t8qijs6ScrP",
"ATubqbssJKtPfyebkmct4jv9YSue8xrhMLa",
"AU9KCwJm6mG9YxSb3LdjVi6LDwRGey1knfy",
"ATwMEAGfNhbRCRSApro8HWG2L65HMMa42KP",
"AU4rMtj3zEJesVQ94Az8ajncNMgtK6uzeHB",
"ATtdkLaHDPZQx3LsUfrKisRcrMkvfg18LGa",
"ATxa6h87rBrNYKDCkagageiPzTMFgcGmefA",
"AU8R9ri7eG968zuJuLQVLMiUzRNXvQwNPwE"
]
随着越来越多的钱包被创建,我们最好限制分批返回结果。我们可以通过 HTTP GET /addresses/seq/{from}/{to} 这个API拿到任意范围的钱包地址,例如
$ curl -X GET 'http://<节点ip>:9922/addresses/seq/5/10'
如果成功将返回类似结果:
[
"ATwMEAGfNhbRCRSApro8HWG2L65HMMa42KP",
"AU4rMtj3zEJesVQ94Az8ajncNMgtK6uzeHB",
"ATtdkLaHDPZQx3LsUfrKisRcrMkvfg18LGa",
"ATxa6h87rBrNYKDCkagageiPzTMFgcGmefA",
"AU8R9ri7eG968zuJuLQVLMiUzRNXvQwNPwE"
]
查询余额可以通过 HTTP GET 调用 /addresses/balance/details/{address}
$ curl -X GET 'http://<节点ip>:9922/addresses/balance/details/AU8R9ri7eG968zuJuLQVLMiUzRNXvQwNPwE'
如果成功将返回类似结果:
{
'address': 'AU8R9ri7eG968zuJuLQVLMiUzRNXvQwNPwE',
'regular': 109010000000, # regular balance
'available': 108910000000, # available balance (regular - leased out)
'effective': 108910000000, # effective balance (regular - leases out + leased in)
'mintingAverage': 108909964800, # for minter used
'height': 643936
}
返回中, available
的值是最终可用余额 (100000000 = 1 VEE).
使用 HTTP POST 调用 /vee/payment API
$ curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'api_key: <节点api密钥>' -d '{ \
"amount": 100000000, \
"fee": 10000000, \
"feeScale": 100, \
"sender": "ATtRykARbyJS1RwNsA6Rn1Um3S7FuVSovHK", \
"attachment": "", \
"recipient": "ATt6P4vSpBvBTHdV5V9PJEHMFp4msJ1fkkX" \
}' 'http://<节点ip>:9922/vee/payment'
在请求的JSON结构中,
amount
是支付给对方的费用,100000000 = 1 VEE。
fee
是交易费,最小交易费10000000 (0.1 VEE)。
feeScale
目前是固定值100。
sender
是支付方的钱包地址。
recipient
是接受方的钱包地址。
attachment
可以说任意字符(最多140个字符),用base58编码填入此项。
如果成功将返回类似结果:
{
"type": 2,
"id": "EoNQyNouEKg8pDcEEPY2dJL9FMQx61YFk1Sn5EJN8H7K",
"fee": 10000000,
"timestamp": 1544083814291691000,
"proofs": [
{
"proofType": "Curve25519",
"publicKey": "3orvgyRKf45FRyiCkcA3CzAGDvyEpBpXZzYGEGZnpZK5",
"signature": "t1X2zmw5a2b9iaLgtsHyHKgEmKo6GCFuMFQsZNqj8ZkzpVbRKhWUttqUDfcjzcn5w7VgVVvf8cetr1mh2d2xypQ"
}
],
"recipient": "ATt6P4vSpBvBTHdV5V9PJEHMFp4msJ1fkkX",
"feeScale": 100,
"amount": 100000000,
"attachment": ""
}
用 HTTP GET 调用 /transactions/address/{address}/limit/{limit} API,例如,
$ curl -X GET 'http://<节点ip>:9922/transactions/address/ATt6P4vSpBvBTHdV5V9PJEHMFp4msJ1fkkX/limit/5'
如果成功将返回类似结果:
[
[
{
"type": 2,
"id": "EoNQyNouEKg8pDcEEPY2dJL9FMQx61YFk1Sn5EJN8H7K",
"fee": 10000000,
"timestamp": 1544083814291691000,
"proofs": [
{
"proofType": "Curve25519",
"publicKey": "3orvgyRKf45FRyiCkcA3CzAGDvyEpBpXZzYGEGZnpZK5",
"signature": "t1X2zmw5a2b9iaLgtsHyHKgEmKo6GCFuMFQsZNqj8ZkzpVbRKhWUttqUDfcjzcn5w7VgVVvf8cetr1mh2d2xypQ"
}
],
"recipient": "ATt6P4vSpBvBTHdV5V9PJEHMFp4msJ1fkkX",
"feeScale": 100,
"amount": 100000000,
"attachment": "",
"status": "Success",
"feeCharged": 10000000
},
{
"type": 4,
"id": "FiMiErppddPfFCmehu1ziKNTqyzBFsLRj6gh9y45JKKD",
"fee": 10000000,
"timestamp": 1543569020372515800,
"proofs": [
{
"proofType": "Curve25519",
"publicKey": "B2Khd89jtnpuzGdnyGRcnKycZMBCo6PsotFcWWi1wMDV",
"signature": "2hpsVXZVs2Wmg5ixD8PqvMJoC3CAqgTqvapYkuFAxbLvoyXRu45q9HXZQyqCzHeiHocGFM8phPkmDuM566Xu59em"
}
],
"feeScale": 100,
"leaseId": "D8mGb2YSGyKr5Q3WATnpQP8JvyDdteXwieo5khwsTEyY",
"status": "Success",
"feeCharged": 10000000,
"lease": {
"type": 3,
"id": "D8mGb2YSGyKr5Q3WATnpQP8JvyDdteXwieo5khwsTEyY",
"fee": 10000000,
"timestamp": 1543569009108564000,
"proofs": [
{
"proofType": "Curve25519",
"publicKey": "B2Khd89jtnpuzGdnyGRcnKycZMBCo6PsotFcWWi1wMDV",
"signature": "8TDUgnkNbrPL6VMLFzDnhZvABfRqXitFX46mmvpohsdeRHKaNtWCs5C7m6avaUH2NjiFS7jGFov1CY5s3W8Zc5V"
}
],
"amount": 100000000,
"recipient": "AU6GsBinGPqW8zUuvmjgwpBNLfyyTU3p83Q",
"feeScale": 100
}
},
{
"type": 3,
"id": "D8mGb2YSGyKr5Q3WATnpQP8JvyDdteXwieo5khwsTEyY",
"fee": 10000000,
"timestamp": 1543569009108564000,
"proofs": [
{
"proofType": "Curve25519",
"publicKey": "B2Khd89jtnpuzGdnyGRcnKycZMBCo6PsotFcWWi1wMDV",
"signature": "8TDUgnkNbrPL6VMLFzDnhZvABfRqXitFX46mmvpohsdeRHKaNtWCs5C7m6avaUH2NjiFS7jGFov1CY5s3W8Zc5V"
}
],
"amount": 100000000,
"recipient": "AU6GsBinGPqW8zUuvmjgwpBNLfyyTU3p83Q",
"feeScale": 100,
"status": "Success",
"feeCharged": 10000000
},
{
"type": 2,
"id": "He17g3JXtbXgMiWCTGwnNMPfvfFH5tvyJfYZ7BiWGBZK",
"fee": 10000000,
"timestamp": 1543568995612184000,
"proofs": [
{
"proofType": "Curve25519",
"publicKey": "CbUPwcCJaMqYSjZGXy4LrkTfV2ncP27Chqyd2QKXfJxn",
"signature": "24fNpVr8qjrKuDNd8JSeZgkSa4BuS44kxupiAYPHxCbbPMBs2DyT7VDnqAWsJkYZxXWadqiQs7HFxW9uVULrGAtt"
}
],
"recipient": "ATt6P4vSpBvBTHdV5V9PJEHMFp4msJ1fkkX",
"feeScale": 100,
"amount": 100000000,
"attachment": "",
"status": "Success",
"feeCharged": 10000000
},
{
"type": 2,
"id": "2FVTJUpUJAhZJWkVYHHCG4nRXkYqwQcKsGEK8uwx3A58",
"fee": 10000000,
"timestamp": 1543568982176328000,
"proofs": [
{
"proofType": "Curve25519",
"publicKey": "B2Khd89jtnpuzGdnyGRcnKycZMBCo6PsotFcWWi1wMDV",
"signature": "3DShPFQLidR1nbTKDrrhpp6SZdiL1hKtjYaGANzGuaWqjpGggPgtrCzw5XYXXktt2sFgWnmFVfTf4gNkmNPNyS2v"
}
],
"recipient": "AU6GsBinGPqW8zUuvmjgwpBNLfyyTU3p83Q",
"feeScale": 100,
"amount": 100000000,
"attachment": "",
"status": "Success",
"feeCharged": 10000000
}
]
]
几个常见的交易类型ID:
2 = 支付交易
3 = 租赁交易
4 = 取消租赁交易
5 = 挖矿交易