EOS主网已经上线,但是市面上还没有特别好用的钱包,所以只能自己动手丰衣足食了,在编译运行EOS代码的时候遇到不少的问题,这边记录一下。 使用Ubuntu 16.04在本地编译是没有遇到什么问题的,基本上一条命令就编译过去了,但是由于大部分的EOS节点都在国外,所以同步区块特别慢,所以还是买了一个美国的ECS,我购买是阿里云硅谷的服务器,github同步的时候十几M一秒,在国内是不敢想象的。
如果是在本地的ubuntu 16.04编译的话,基本上3条命令就可以编译出来了,跟着官方文档,没有出现什么意外
https://github.com/EOSIO/eos/wiki/Local-Environment#2-building-eosio
git clone https://github.com/EOSIO/eos --recursive cd ~/eos ./eosio_build.sh
apt update apt upgrade之后运行上面3条命令,基本没有遇到问题。都能直接过。我主要记录一下在阿里云的服务器上编译的问题。购买的是阿里云的ubuntu 16.04版本服务器,首先一个是云服务器只有2G内存,40G硬盘,编译的时候报错内存和硬盘不够,修改eosio_build_ubuntu.sh文件
vi scripts/eosio_build_ubuntu.sh # if [ "${MEM_MEG}" -lt 7000 ]; then # printf "\\tYour system must have 7 or more Gigabytes of physical memory installed.\\n" # printf "\\tExiting now.\\n" # exit 1 # fi # if [ "${DISK_AVAIL%.*}" -lt "${DISK_MIN}" ]; then # printf "\\tYou must have at least %sGB of available storage to install EOSIO.\\n" "${DISK_MIN}" # printf "\\tExiting now.\\n" # exit 1 # fi
把这些检测都注释掉,然后就可以运行./eosio_build.sh了,然后中间又报错
make: the '-j' option requires a positive integer argument Usage: make [options] [target] ... Options: -b, -m Ignored for compatibility. -B, --always-make Unconditionally make all targets. -C DIRECTORY, --directory=DIRECTORY Change to DIRECTORY before doing anything. -d Print lots of debugging information. --debug[=FLAGS] Print various types of debugging information. -e, --environment-overrides Environment variables override makefiles. --eval=STRING Evaluate STRING as a makefile statement. -f FILE, --file=FILE, --makefile=FILE Read FILE as a makefile. -h, --help Print this message and exit. -i, --ignore-errors Ignore errors from recipes. -I DIRECTORY, --include-dir=DIRECTORY Search DIRECTORY for included makefiles. -j [N], --jobs[=N] Allow N jobs at once; infinite jobs with no arg. -k, --keep-going Keep going when some targets can't be made. -l [N], --load-average[=N], --max-load[=N] Don't start multiple jobs unless load is below N. -L, --check-symlink-times Use the latest mtime between symlinks and target. -n, --just-print, --dry-run, --recon Don't actually run any recipe; just print them. -o FILE, --old-file=FILE, --assume-old=FILE Consider FILE to be very old and don't remake it. -O[TYPE], --output-sync[=TYPE] Synchronize output of parallel jobs by TYPE. -p, --print-data-base Print make's internal database. -q, --question Run no recipe; exit status says if up to date. -r, --no-builtin-rules Disable the built-in implicit rules. -R, --no-builtin-variables Disable the built-in variable settings. -s, --silent, --quiet Don't echo recipes. -S, --no-keep-going, --stop Turns off -k. -t, --touch Touch targets instead of remaking them. --trace Print tracing information. -v, --version Print the version number of make and exit. -w, --print-directory Print the current directory. --no-print-directory Turn off -w, even if it was turned on implicitly. -W FILE, --what-if=FILE, --new-file=FILE, --assume-new=FILE Consider FILE to be infinitely new. --warn-undefined-variables Warn when an undefined variable is referenced. This program built for x86_64-pc-linux-gnu Report bugs toError compiling LLVM and clang with EXPERIMENTAL WASM support.1 Exiting now.
我试了一下,从mongo-c-driver 到llvm全部出错,这个应该是make的问题?好吧,看来脚本没法搞了,就自己手动一个一个编译。运行./eosio_build.sh的时候哪个出错,就在tmp目录下根据下面这个文本教程做就可以了。 只是有一个问题,mongo-cxx-driver驱动不能使用教程的最新版。
https://bihu.com/article/179190
把git clone https://github.com/mongodb/mongo-cxx-driver.git –branch releases/stable –depth 1
换成git clone https://github.com/mongodb/mongo-cxx-driver.git –branch releases/v3.2 –depth 1
最新版本的mongo-cxx-driver驱动依赖高版本的 libbson 库,我们换成3.2就可以了,不然编译会失败。
从mongo-c-driver mongo-cxx-driver 到secp256k1-zkp到 llvm我都是手动编译的,另外根据那个教程在编译llvm的时候也有问题,因为EOS的检测路径改了,在script/eosio_build_ubuntu.sh目录下面看到有这个命令
printf "\\n\\tChecking for LLVM with WASM support.\\n" if [ ! -d "${HOME}/opt/wasm/bin" ]; then # Build LLVM and clang with WASM support: printf "\\tInstalling LLVM with WASM\\n" if ! cd "${TEMP_DIR}" then printf "\\n\\tUnable to cd into directory %s.\\n" "${TEMP_DIR}" printf "\\n\\tExiting now.\\n" exit 1; fi if ! mkdir "${TEMP_DIR}/llvm-compiler" 2>/dev/null then
检测的是home目录下的文件,所以根据上面的教程在llvm cmake的时候需要改动一下,将
cmake -G “Unix Makefiles” -DCMAKE_INSTALL_PREFIX=.. -DLLVM_TARGETS_TO_BUILD= -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly -DCMAKE_BUILD_TYPE=Release ..
改成
cmake -G “Unix Makefiles” -DCMAKE_INSTALL_PREFIX=”${HOME}/opt/wasm” -DLLVM_TARGETS_TO_BUILD= -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly -DCMAKE_BUILD_TYPE=Release ../
安装目录改到了home目录下面才能被EOS的eosio_build_ubuntu.sh检测到。我日,搞到这里才发现之前为什么make会失败,之前的make失败是因为本地ubuntu 的shell都有这个变量${JOBS}在阿里云的机器上没有所以失败才会产生之前的make失败。。。惨痛的教训,用vi打开eosio_build_ubuntu.sh输入以下命令
:0, $s/make -j”${JOBS}”/make -j2/g
这条命令的意思是把所有的make -j”${JOBS}”替换成make -j2因为我买的阿里云服务器是双核的,你可以根据具体情况自己修改。这样就可以像本地一样直接编译了。不过还好,也算是手工搞了一遍,把EOS依赖库都熟悉了一遍,不过搞了几天,这个代价有点大。趟了一路的雷!!!
出现这个界面就表示编译完成,然后就可以进入build目录make install安装EOS,这样电脑中就有EOS命令了,接下来就是开始运行程序同步节点了,首先创建创世同步区块
{ "initial_timestamp": "2018-06-08T08:08:08.888", "initial_key": "EOS7EarnUhcyYqmdnPon8rm7mBCTnBoot6o7fE2WzjvEX2TdggbL3", "initial_configuration": { "max_block_net_usage": 1048576, "target_block_net_usage_pct": 1000, "max_transaction_net_usage": 524288, "base_per_transaction_net_usage": 12, "net_usage_leeway": 500, "context_free_discount_net_usage_num": 20, "context_free_discount_net_usage_den": 100, "max_block_cpu_usage": 200000, "target_block_cpu_usage_pct": 1000, "max_transaction_cpu_usage": 150000, "min_transaction_cpu_usage": 100, "max_transaction_lifetime": 3600, "deferred_trx_expiration_window": 600, "max_transaction_delay": 3888000, "max_inline_action_size": 4096, "max_inline_action_depth": 4, "max_authority_depth": 6 } }
保存成genesis.json,然后运行nodeos –genesis-json genesis.json –config-dir /home/eos_datadir –data-dir /home/eos_datadir –delete-all-blocks这条命令的意思是使用genesis.json文件初始化区块链节点,然后配置文件和数据目录设置到/home/eos_datadir下面。
root@XS2323677106:/home/eos_datadir# nodeos --genesis-json genesis.json --config-dir /home/eos_datadir --data-dir /home/eos_datadir --delete-all-blocks 640251ms thread-0 chain_plugin.cpp:209 plugin_initialize ] initializing chain plugin 640252ms thread-0 chain_plugin.cpp:316 plugin_initialize ] Deleting state database and blocks 640366ms thread-0 chain_plugin.cpp:379 plugin_initialize ] Using genesis state provided in '/home/eos_datadir/genesis.json' 640366ms thread-0 chain_plugin.cpp:385 plugin_initialize ] Starting up fresh blockchain with provided genesis state. 641068ms thread-0 http_plugin.cpp:290 plugin_initialize ] configured http to listen on 127.0.0.1:8888 641069ms thread-0 net_plugin.cpp:2948 plugin_initialize ] Initialize net plugin 641069ms thread-0 net_plugin.cpp:2972 plugin_initialize ] host: 0.0.0.0 port: 9876 641069ms thread-0 net_plugin.cpp:3044 plugin_initialize ] my node_id is f005b1ca544075192ef714ffc02bd56677b3b3c013df8ccceeaaa65ae3f786aa 641069ms thread-0 main.cpp:104 main ] nodeos version 90fefdd1 641069ms thread-0 main.cpp:105 main ] eosio root is /root/.local/share 641070ms thread-0 controller.cpp:1201 startup ] No head block in fork db, perhaps we need to replay 641070ms thread-0 controller.cpp:305 initialize_fork_db ] Initializing new blockchain with genesis state 641110ms thread-0 chain_plugin.cpp:450 plugin_startup ] starting chain in read/write mode 641110ms thread-0 chain_plugin.cpp:455 plugin_startup ] Blockchain started; head block is #1, genesis timestamp is 2018
出现这个界面就马上CTRL+Z停下来,到/home/eos_datadir下面去修改config文件,改成这样,主要是配置节点信息
# the endpoint upon which to listen for incoming connections (eosio::bnet_plugin) bnet-endpoint = 0.0.0.0:4321 # this peer will request only irreversible blocks from other nodes (eosio::bnet_plugin) bnet-follow-irreversible = 0 # the number of threads to use to process network messages (eosio::bnet_plugin) # bnet-threads = # remote endpoint of other node to connect to; Use multiple bnet-connect options as needed to compose a network (eosio::bnet_plugin) # bnet-connect = # this peer will request no pending transactions from other nodes (eosio::bnet_plugin) bnet-no-trx = false # The string used to format peers when logging messages about them. Variables are escaped with ${}. # Available Variables: # _name self-reported name # # _id self-reported ID (Public Key) # # _ip remote IP address of peer # # _port remote port number of peer # # _lip local IP address connected to peer # # _lport local port number connected to peer # # (eosio::bnet_plugin) bnet-peer-log-format = ["${_name}" ${_ip}:${_port}] # the location of the blocks directory (absolute path or relative to application data dir) (eosio::chain_plugin) blocks-dir = "blocks" # Pairs of [BLOCK_NUM,BLOCK_ID] that should be enforced as checkpoints. (eosio::chain_plugin) # checkpoint = # Override default WASM runtime (eosio::chain_plugin) # wasm-runtime = # Override default maximum ABI serialization time allowed in ms (eosio::chain_plugin) # abi-serializer-max-time-ms = # Maximum size (in MB) of the chain state database (eosio::chain_plugin) chain-state-db-size-mb = 1024 # Maximum size (in MB) of the reversible blocks database (eosio::chain_plugin) reversible-blocks-db-size-mb = 340 # print contract's output to console (eosio::chain_plugin) contracts-console = false # Account added to actor whitelist (may specify multiple times) (eosio::chain_plugin) # actor-whitelist = # Account added to actor blacklist (may specify multiple times) (eosio::chain_plugin) # actor-blacklist = # Contract account added to contract whitelist (may specify multiple times) (eosio::chain_plugin) # contract-whitelist = # Contract account added to contract blacklist (may specify multiple times) (eosio::chain_plugin) # contract-blacklist = # Action (in the form code::action) added to action blacklist (may specify multiple times) (eosio::chain_plugin) # action-blacklist = # Public key added to blacklist of keys that should not be included in authorities (may specify multiple times) (eosio::chain_plugin) # key-blacklist = # Track actions which match receiver:action:actor. Actor may be blank to include all. Receiver and Action may not be blank. (eosio::history_plugin) # filter-on = # PEM encoded trusted root certificate (or path to file containing one) used to validate any TLS connections made. (may specify multiple times) # (eosio::http_client_plugin) # https-client-root-cert = # true: validate that the peer certificates are valid and trusted, false: ignore cert errors (eosio::http_client_plugin) https-client-validate-peers = 1 # The local IP and port to listen for incoming http connections; set blank to disable. (eosio::http_plugin) http-server-address = 127.0.0.1:8888 # The local IP and port to listen for incoming https connections; leave blank to disable. (eosio::http_plugin) # https-server-address = # Filename with the certificate chain to present on https connections. PEM format. Required for https. (eosio::http_plugin) # https-certificate-chain-file = # Filename with https private key in PEM format. Required for https (eosio::http_plugin) # https-private-key-file = # Specify the Access-Control-Allow-Origin to be returned on each request. (eosio::http_plugin) # access-control-allow-origin = # Specify the Access-Control-Allow-Headers to be returned on each request. (eosio::http_plugin) # access-control-allow-headers = # Specify the Access-Control-Max-Age to be returned on each request. (eosio::http_plugin) # access-control-max-age = # Specify if Access-Control-Allow-Credentials: true should be returned on each request. (eosio::http_plugin) access-control-allow-credentials = false # The maximum body size in bytes allowed for incoming RPC requests (eosio::http_plugin) max-body-size = 1048576 # Append the error log to HTTP responses (eosio::http_plugin) verbose-http-errors = false # The actual host:port used to listen for incoming p2p connections. (eosio::net_plugin) p2p-listen-endpoint = 0.0.0.0:9876 # An externally accessible host:port for identifying this node. Defaults to p2p-listen-endpoint. (eosio::net_plugin) p2p-peer-address = p2p.one.eosdublin.io:9876 p2p-peer-address = eu-west-nl.eosamsterdam.net:9876 p2p-peer-address = p2p.mainnet.eosgermany.online:9876 p2p-peer-address = 35.197.190.234:19878 p2p-peer-address = p2p.genereos.io:9876 p2p-peer-address = fullnode.eoslaomao.com:443 p2p-peer-address = new.eoshenzhen.io:10034 p2p-peer-address = node1.eosphere.io:9876 p2p-peer-address = p2p.meet.one:9876 p2p-peer-address = bp.eosbeijing.one:8080 p2p-peer-address = peer1.mainnet.helloeos.com.cn:80 p2p-peer-address = p2p-public.hkeos.com:19875 p2p-peer-address = pub1.eostheworld.io:9876 p2p-peer-address = eu1.eosdac.io:49876 p2p-peer-address = peer.eosio.sg:9876 # The public endpoint of a peer node to connect to. Use multiple p2p-peer-address options as needed to compose a network. (eosio::net_plugin) # p2p-peer-address = # Maximum number of client0nodes from any single IP address (eosio::net_plugin) p2p-max-nodes-per-host = 10 # The name supplied to identify this node amongst the peers. (eosio::net_plugin) agent-name = "joenEOSTestAgent" # Can be 'any' or 'producers' or 'specified' or 'none'. If 'specified', peer-key must be specified at least once. If only 'producers', peer-key is not required. 'producers' and 'specified' may be combined. (eosio::net_plugin) allowed-connection = any # Optional public key of peer allowed to connect. May be used multiple times. (eosio::net_plugin) # peer-key = # Tuple of [PublicKey, WIF private key] (may specify multiple times) (eosio::net_plugin) # peer-private-key = peer-private-key = ["EOS6qTvpRYx35aLonqUkWAMwAf3mFVugYfQCbjV67zw2aoe7Vx7qd", "5JroNC1B4pz9gJzNZeU7tkU6YMtoeWRCr4CJJwKsVXnJhRbKXSC"] # Maximum number of clients from which connections are accepted, use 0 for no limit (eosio::net_plugin) max-clients = 25 # number of seconds to wait before cleaning up dead connections (eosio::net_plugin) connection-cleanup-period = 30 # True to require exact match of peer network version. (eosio::net_plugin) network-version-match = 1 # number of blocks to retrieve in a chunk from any individual peer during synchronization (eosio::net_plugin) sync-fetch-span = 100 # maximum sizes of transaction or block messages that are sent without first sending a notice (eosio::net_plugin) max-implicit-request = 1500 # Enable expirimental socket read watermark optimization (eosio::net_plugin) use-socket-read-watermark = 0 # The string used to format peers when logging messages about them. Variables are escaped with ${ }. # Available Variables: # _name self-reported name # # _id self-reported ID (64 hex characters) # # _sid first 8 characters of _peer.id # # _ip remote IP address of peer # # _port remote port number of peer # # _lip local IP address connected to peer # # _lport local port number connected to peer # # (eosio::net_plugin) peer-log-format = ["${_name}" ${_ip}:${_port}] # Enable block production, even if the chain is stale. (eosio::producer_plugin) enable-stale-production = false # Start this node in a state where production is paused (eosio::producer_plugin) pause-on-startup = false # Limits the maximum time (in milliseconds) that is allowed a pushed transaction's code to execute before being considered invalid (eosio::producer_plugin) max-transaction-time = 30 # Limits the maximum age (in seconds) of the DPOS Irreversible Block for a chain this node will produce blocks on (use negative value to indicate unlimited) (eosio::producer_plugin) max-irreversible-block-age = -1 # ID of producer controlled by this node (e.g. inita; may specify multiple times) (eosio::producer_plugin) # producer-name = # (DEPRECATED - Use signature-provider instead) Tuple of [public key, WIF private key] (may specify multiple times) (eosio::producer_plugin) # private-key = # Key=Value pairs in the form = # Where: # is a string form of a vaild EOSIO public key # # is a string in the form : # # is KEY, or KEOSD # # KEY: is a string form of a valid EOSIO private key which maps to the provided public key # # KEOSD: is the URL where keosd is available and the approptiate wallet(s) are unlocked (eosio::producer_plugin) signature-provider = EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV=KEY:5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3 # Limits the maximum time (in milliseconds) that is allowd for sending blocks to a keosd provider for signing (eosio::producer_plugin) keosd-provider-timeout = 5 # Lag in number of blocks from the head block when selecting the reference block for transactions (-1 means Last Irreversible Block) (eosio::txn_test_gen_plugin) txn-reference-block-lag = 0 # The path of the wallet files (absolute path or relative to application data dir) (eosio::wallet_plugin) wallet-dir = "." # Timeout for unlocked wallet in seconds (default 900 (15 minutes)). Wallets will automatically lock after specified number of seconds of inactivity. Activity is defined as any wallet command e.g. list-wallets. (eosio::wallet_plugin) unlock-timeout = 900 # Plugin(s) to enable, may be specified multiple times # plugin = plugin = eosio::chain_api_plugin plugin = eosio::history_api_plugin plugin = eosio::chain_plugin plugin = eosio::history_plugin plugin = eosio::net_plugin plugin = eosio::net_api_plugin
然后再次运行nodeos –genesis-json genesis.json –config-dir /home/eos_datadir –data-dir /home/eos_datadir –delete-all-blocks这样节点就起来了,如果需要自己配置节点,可以在这个网站查看节点列表
https://eosnodes.privex.io/
或者https://eospark.com/MainNet/上自己去查看节点的接入点
root@XS2323677106:~# cleos get info { "server_version": "90fefdd1", "chain_id": "aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906", "head_block_num": 1582, "last_irreversible_block_num": 1581, "last_irreversible_block_id": "0000062d59fe2a92d371250ed2541a2c6dcb5d90a69f179e7b238273a988cd83", "head_block_id": "0000062ec80857a32e3fcdb61e93fbcaddf710309c9fa8156a9512a6c8a2960d", "head_block_time": "2018-06-09T12:11:24.000", "head_block_producer": "eosio", "virtual_block_cpu_limit": 317584735, "virtual_block_net_limit": 5098012, "block_cpu_limit": 99999900, "block_net_limit": 1048576 }
可以输入上面的命令查看是不是链接到了公链上面,chain_id 是否下面这行代码,如果是就表示是公链了:aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906
还可以运行这个命令cleos get block 191
发现这个191区块存在这样一笔交易,eosio 账户给 b1账户转了 10个EOS,并且备注了这样一句话:
Never doubt that a small group of thoughtful, committed citizens can change the world; indeed, it’s the only thing that ever has – eosacknowledgments.io
翻译成中文是:永远不要怀疑一小群有思想、有责任心的公民能改变世界,事实上,这是唯一的事情。
同步区块也是也非常麻烦的事情,我们可以也可以使用人家的公共API在https://eospark.com/MainNet/上面看靠前的节点,找到接入点,然后本地使用cleos -u就可以使用人家的节点了,这样就不需要自己同步区块了。
cleos -u http://node1.zbeos.com:8888 get block 191
接下来就是EOS的命令行钱包的使用了,可以直接参考下面的文章
https://eosfans.io/topics/701
https://steemit.com/eos/@oflyhigh/2dgsna-eos
https://zhuanlan.zhihu.com/p/37891815