提交 528fc7a8 编写于 作者: B Bart Wyatt

merging changes to master @b1804199

......@@ -175,6 +175,7 @@ source ~/.bash_profile
## Building and running a node
### Getting the code
To download all of the code, download Eos and a recursion or two of submodules. The easiest way to get all of this is to do a recursive clone:
`git clone https://github.com/eosio/eos --recursive`
......@@ -359,7 +360,7 @@ code hash: 0000000000000000000000000000000000000000000000000000000000000000
With an account for a contract created, you can upload a sample contract:
```commandline
./eosc set contract currency ../../../contracts/currency/currency.wast ../../../contracts/currency/currency.abi
./eosc set contract currency ../../contracts/currency/currency.wast ../../contracts/currency/currency.abi
```
As a response you should get a json with a `transaction_id` field. Your contract was successfully uploaded!
......@@ -507,5 +508,5 @@ curl http://127.0.0.1:8888/v1/chain/get_info
You can run the `eosc` commands via `docker exec` command. For example:
```
docker exec docker_eos_1 eosc contract exchange contracts/exchange/exchange.wast contracts/exchange/exchange.abi
docker exec docker_eos_1 eosc contract exchange build/contracts/exchange/exchange.wast build/contracts/exchange/exchange.abi
```
file(GLOB SOURCE_FILES "*.cpp")
add_wast_target(currency "${SOURCE_FILES}" "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_SOURCE_DIR})
file(GLOB ABI_FILES "*.abi")
add_wast_target(currency "${SOURCE_FILES}" "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_BINARY_DIR})
configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY)
\ No newline at end of file
......@@ -14,6 +14,8 @@
- [Transfer EOS](#transfereos)
- [Getting Transaction](#gettingtransaction)
- [Creating a Contract](#createcontract)
- [Pushing Message to Contract](#pushmessage)
- [Querying Contract](#querycontract)
- [Connecting to Particular Node](#particularnode)
- [Using Separate Wallet App](#separatewallet)
- [Skipping Signature](#skippingsignature)
......@@ -203,6 +205,15 @@
}
}
```
You can see that `tester` is now the controlled_account under `inita`
```
$ ./eosc get servants inita
{
"controlled_accounts": [
"tester"
]
}
```
@section transfereos Transfer EOS
......@@ -490,8 +501,59 @@
}
```
@section pushmessage Pushing Message to Contract
After the contract is published it initially allocates all of the currency to the `currency` account. So lets transfer some of it to our tester.
We can query the blockchain for the .abi of the contract, on which we can check the list of available actions and their respective message structure
```
$ ./eosc get code --a currency.abi currency
code hash: 9b9db1a7940503a88535517049e64467a6e8f4e9e03af15e9968ec89dd794975
saving abi to currency.abi
$ cat currency.abi
{
"types": [{
"newTypeName": "AccountName",
"type": "Name"
}
],
"structs": [{
"name": "transfer",
"base": "",
"fields": {
"from": "AccountName",
"to": "AccountName",
"amount": "UInt64"
}
},{
"name": "account",
"base": "",
"fields": {
"account": "Name",
"balance": "UInt64"
}
}
],
"actions": [{
"action": "transfer",
"type": "transfer"
}
],
"tables": [{
"table": "account",
"indextype": "i64",
"keynames": [
"account"
],
"keytype": [],
"type": "account"
}
]
}
```
From the above abi, we can see that `currency` contract accepts an action called `transfer` that accepts message with fields `from`, `to`, and `amount`.
```
$ ./eosc push message currency transfer '{"from":"currency","to":"tester","amount":50}' -S currency -S tester -p currency@active
1589302ms thread-0 main.cpp:271 operator() ] Converting argument to binary...
......@@ -540,18 +602,6 @@
}
}
```
We can check the balance of `tester` inside its scope, and see it has balance of 50
```
./eosc get table tester currency account
{
"rows": [{
"account": "account",
"balance": 50
}
],
"more": true
}
```
Now we can transfer it from `tester` to `inita` and require the permission of `tester`. This should drain the balance of `tester` to 0.
......@@ -626,6 +676,30 @@
[...snipped...]
```
@section querycontract Querying Contract
After doing the transfer action on `currency` contract, we can verify the amount of token held by each account by looking at `currency`'s `account` table.
This table is stored on the scope of each account instead of on `currency` scope.
```
$./eosc get table tester currency account
{
"rows": [],
"more": false
}
$./eosc get table inita currency account
{
"rows": [{
"account": "account",
"balance": 50
}
],
"more": true
}
```
@section particularnode Connecting to Particular Node
By default, `eosc` will connect to `eosd` running on localhost port 8888. You can connect to another `eosd` node by specifying its host and port.
......
file(GLOB SOURCE_FILES "*.cpp")
add_wast_target(exchange "${SOURCE_FILES}" "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_SOURCE_DIR})
file(GLOB ABI_FILES "*.abi")
add_wast_target(exchange "${SOURCE_FILES}" "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_BINARY_DIR})
configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY)
add_dependencies( exchange currency )
file(GLOB SOURCE_FILES "*.cpp")
add_wast_target(infinite "${SOURCE_FILES}" "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_SOURCE_DIR})
add_wast_target(infinite "${SOURCE_FILES}" "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_BINARY_DIR})
file(GLOB SOURCE_FILES "*.cpp")
add_wast_target(simpledb "${SOURCE_FILES}" "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_SOURCE_DIR})
file(GLOB ABI_FILES "*.abi")
add_wast_target(simpledb "${SOURCE_FILES}" "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_BINARY_DIR})
configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY)
file(GLOB SOURCE_FILES "*.cpp")
add_wast_target(social "${SOURCE_FILES}" "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_SOURCE_DIR})
\ No newline at end of file
add_wast_target(social "${SOURCE_FILES}" "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_BINARY_DIR})
\ No newline at end of file
file(GLOB SOURCE_FILES "*.cpp")
add_wast_target(test_api "${SOURCE_FILES}" "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_SOURCE_DIR})
add_wast_target(test_api "${SOURCE_FILES}" "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_BINARY_DIR})
此差异已折叠。
......@@ -14,7 +14,6 @@ set(sources
string_escape.cpp
tempdir.cpp
words.cpp
wasm.cpp
${HEADERS})
#configure_file("${CMAKE_CURRENT_SOURCE_DIR}/git_revision.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/git_revision.cpp" @ONLY)
......
#pragma once
#include <string>
#include <vector>
namespace eos { namespace utilities {
std::vector<uint8_t> assemble_wast(const std::string& wast);
} } // namespace eos::utilities
#include <eos/utilities/wasm.hpp>
#include <fc/exception/exception.hpp>
#include <Inline/BasicTypes.h>
#include <IR/Module.h>
#include <IR/Validate.h>
#include <WAST/WAST.h>
#include <WASM/WASM.h>
#include <iostream>
#include <iomanip>
namespace eos { namespace utilities {
std::vector<uint8_t> assemble_wast( const std::string& wast ) {
IR::Module module;
std::vector<WAST::Error> parseErrors;
WAST::parseModule(wast.c_str(),wast.size(),module,parseErrors);
if(parseErrors.size())
{
// Print any parse errors;
std::cerr << "Error parsing WebAssembly text file:" << std::endl;
for(auto& error : parseErrors)
{
std::cerr << ":" << error.locus.describe() << ": " << error.message.c_str() << std::endl;
std::cerr << error.locus.sourceLine << std::endl;
std::cerr << std::setw(error.locus.column(8)) << "^" << std::endl;
}
FC_ASSERT( !"error parsing wast" );
}
try
{
// Serialize the WebAssembly module.
Serialization::ArrayOutputStream stream;
WASM::serialize(stream,module);
return stream.getBytes();
}
catch(Serialization::FatalSerializationException exception)
{
std::cerr << "Error serializing WebAssembly binary file:" << std::endl;
std::cerr << exception.message << std::endl;
throw;
}
}
} } // namespace eos::utilities
......@@ -96,7 +96,9 @@ void producer_plugin::set_program_options(
auto private_key_default = std::make_pair(chain::public_key_type(default_priv_key.get_public_key()),
eos::utilities::key_to_wif(default_priv_key));
command_line_options.add_options()
boost::program_options::options_description producer_options;
producer_options.add_options()
("enable-stale-production", boost::program_options::bool_switch()->notifier([this](bool e){my->_production_enabled = e;}), "Enable block production, even if the chain is stale.")
("required-participation", boost::program_options::bool_switch()->notifier([this](int e){my->_required_producer_participation = uint32_t(e*config::Percent1);}), "Percent of producers (0-99) that must be participating in order to produce blocks")
("producer-name,p", boost::program_options::value<vector<string>>()->composing()->multitoken(),
......@@ -105,7 +107,8 @@ void producer_plugin::set_program_options(
fc::json::to_string(private_key_default)),
"Tuple of [PublicKey, WIF private key] (may specify multiple times)")
;
config_file_options.add(command_line_options);
command_line_options.add(producer_options);
config_file_options.add(producer_options);
}
template<typename T>
......
......@@ -379,7 +379,9 @@ launcher_def::write_config_file (eosd_def &node) {
<< "\",\"" << kp.wif_private_key << "\"]\n";
}
cfg << "plugin = eos::producer_plugin\n"
<< "plugin = eos::chain_api_plugin\n";
<< "plugin = eos::chain_api_plugin\n"
<< "plugin = eos::account_history_plugin\n"
<< "plugin = eos::account_history_api_plugin\n";
for (auto &p : node.producers) {
cfg << "producer-name = " << p << "\n";
}
......
digraph G
{
initg->initb [dir="both"]
initg->initc [dir="both"]
initg->initd [dir="both"]
initg->inite [dir="both"]
initg->initf [dir="both"]
initg->inita [dir="both"]
inita->initb [dir="both"]
inita->initd [dir="both"]
inita->initf [dir="both"]
inita->inith [dir="both"]
inita->initj [dir="both"]
initb->initc [dir="both"]
initb->inite [dir="both"]
initb->initg [dir="both"]
initb->initi [dir="both"]
initb->initk [dir="both"]
initc->initd [dir="both"]
initc->initf [dir="both"]
initc->inith [dir="both"]
initc->initj [dir="both"]
initd->inite [dir="both"]
initd->initg [dir="both"]
initd->initi [dir="both"]
initd->initk [dir="both"]
inite->initf [dir="both"]
inite->inith [dir="both"]
inite->initj [dir="both"]
initf->initg [dir="both"]
initf->initi [dir="both"]
initf->initk [dir="both"]
initg->inith [dir="both"]
initg->initi [dir="both"]
initg->initj [dir="both"]
initg->initk [dir="both"]
inith->initi [dir="both"]
inith->initk [dir="both"]
initi->initj [dir="both"]
initi->initk [dir="both"]
initj->initk [dir="both"]
}
star.png

45.7 KB | W: | H:

star.png

117.9 KB | W: | H:

star.png
star.png
star.png
star.png
  • 2-up
  • Swipe
  • Onion skin
[toc]
# EOS Testnet
#EOS Testnet
To date, all work done to experiment with the EOS blockchain has been performed using a single instance of eosd hosting all 21 block producers. While this is a perfectly valid solution for validating features of the blockchain, developing new contracts, or whatever, it does not scale. Nor does it expose the sort of issues raised when contract and block data must be shared across multiple instances. Providing the ability to scale involves deploying multiple eosd nodes across many hosts and lining then into a peer-to-peer (p2p) network. Composing this network involves tailoring and distributing configuration files, coordinating starts and stops and other tasks.
Doing this manually is a tedious task and easily error prone. Fortunately a solution is provided, in the form of the Launcher application, described below.
......@@ -33,26 +33,26 @@ Network topology or "shape" describes how the nodes are connected in order to sh
The Launcher has definitions of three different network "shapes" based on inter-nodal connections, which can be selected by a command line option, or you can supply your own network topology by editing the Launcher generated configuration file.
#### Ring network
####Ring network
![](ring.png "Ring Diagram")
This is the simplest network, where each node identifies just the node next to it as it's only peer.
#### Star network
####Star network
![](star.png "Star Diagram")
A "star" is intended to support the use larger number nodes in the testnet. In this case the number of peers connected to a node and the distribution of those nodes varies based on the number of nodes in the network.
A "star" is intended to support a larger number of nodes in the testnet. In this case the number of peers connected to a node and the distribution of those nodes varies based on the number of nodes in the network.
#### Mesh network
####Mesh network
![](mesh.png "Mesh Diagram")
In a "mesh" network, each node is connected to as many peer nodes as possible.
# The Launcher Application
#The Launcher Application
To address the complexity implied by distributing multiple eosd nodes across a LAN or a wider network, the launcher application was created.
Based on a handful of command line arguments the Launcher is able to compose per-node configuration files, distribute these files securely amongst the peer hosts, then start up the multiple instances of eosd.
Eosd instances started this way have their output logged in individual text files. Finally the launcher application is also able to shut down some or all of the test network.
## Running the Launcher application
##Running the Launcher application
The launcher program is used to configure and deploy producing and non-producing eosd nodes that talk to each other using configured routes. The configuration for each node is stored in separate directories, permitting multiple nodes to be active on the same host, assuming the machine has sufficient memory and disk space for multiple eosd instances. The launcher makes use of multiple configuration sources in order to deploy a testnet. A handful of command line arguments can be used to set up simple local networks.
......@@ -145,7 +145,7 @@ The ssh helper fields are paths to ssh and scp, an identity if necessary, and an
The rest of the testnet.json file is the collection of node descriptors. The fragment shown above was created with the command line `programs/launcher/launcher -p6 -s mesh -o testnet.json` and then edited to refer to a remote host named "remoteserv."
### Elements Of The JSON File
###Elements Of The JSON File
This table describes all of the key/value pairs used in the testnet.json file.
|Value | Description
......@@ -177,7 +177,7 @@ keys | specify the authentication tokens for this node.
peers | this list indicates the other nodes in the network to which this one actively connects. Since this file may be edited to alter the hostname, public name, or p2p port values, the peers list here holds aliases for the actual endpoints eventually written to the individual config.ini files.
producers | this list identifies which of the producers from the genesis.json file are held by this node. Note that the launcher uses a round-robin algorithm to spread the producer instances across the producing nodes.
### Provisioning Distributed Servers
###Provisioning Distributed Servers
The ssh_helper section of the testnet.json file contains the ssh elements necessary to connect and issue commands to other servers. In addition to the ssh_helper section which provides access to global configuration settings, the per-node configuration may provide overriding identity and connection arguments.
It is also necessary to provision the server by at least copying the eosd executable, and the genesis.json files to their appropriate locations relative to some named EOS root directory. For example, I defined the EOS root to be `/home/phil/blockchain/eos`. When run, the launcher will run through a variety of shell commands using ssh and finally using scp to copy a config.ini file to the appropriate data directory on the remote.
......@@ -196,7 +196,7 @@ The launcher app creates a separate date and configuration directory for each no
A file called "last_run.json" contains hints for a later instance of the launcher to be able to kill local and remote nodes when run with -k.
# What Remains To Be Done
#What Remains To Be Done
Functionality that remains to be implemented: caching signed transactions then purging them on a schedule. Sending summaries of blocks rather than whole blocks. Optimizing the routing between nodes. Failover during new node synchronization if a peer fails to respond timely enough
......
......@@ -76,7 +76,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
#define SETCODE3(chain, acct, wast) \
{ \
auto wasm = eos::utilities::assemble_wast(wast); \
auto wasm = eos::chain::wast_to_wasm(wast); \
types::setcode handler; \
handler.account = #acct; \
handler.code.assign(wasm.begin(), wasm.end()); \
......
#pragma once
#include <eos/utilities/wasm.hpp>
#include <eos/chain/wast_to_wasm.hpp>
#include "macro_support.hpp"
......
......@@ -3,7 +3,7 @@
error()
{
(>&2 echo $1)
cleanup
killAll
exit 1
}
......@@ -15,26 +15,59 @@ verifyErrorCode()
fi
}
cleanup()
killAll()
{
programs/launcher/launcher -k 9
kill -9 $WALLETD_PROC_ID
}
cleanup()
{
rm -rf tn_data_0
rm -rf tn_wallet_0
rm -rf test_wallet_0
}
# result stored in HEAD_BLOCK_NUM
getHeadBlockNum()
{
INFO="$(programs/eosc/eosc get info)"
verifyErrorCode "eosc get info"
HEAD_BLOCK_NUM="$(echo "$INFO" | awk '/head_block_num/ {print $2}')"
# remove trailing coma
HEAD_BLOCK_NUM=${HEAD_BLOCK_NUM%,}
}
waitForNextBlock()
{
getHeadBlockNum
NEXT_BLOCK_NUM=$((HEAD_BLOCK_NUM+1))
while [ "$HEAD_BLOCK_NUM" -lt "$NEXT_BLOCK_NUM" ]; do
sleep 0.25
getHeadBlockNum
done
}
# cleanup from last run
cleanup
INITA_PRV_KEY="5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"
INITB_PRV_KEY="5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"
LOG_FILE=eosd_run_test.log
# eosd
programs/launcher/launcher -p 1
programs/launcher/launcher
verifyErrorCode "launcher"
sleep 9
sleep 7
count=`grep -c "generated block" tn_data_0/stderr.txt`
if [ $count == 0 ]; then
if [[ $count == 0 ]]; then
error "FAILURE - no blocks produced"
fi
# create 2 keys
# save starting block number
getHeadBlockNum
START_BLOCK_NUM=$HEAD_BLOCK_NUM
# create 3 keys
KEYS="$(programs/eosc/eosc create key)"
verifyErrorCode "eosc create key"
PRV_KEY1="$(echo "$KEYS" | awk '/Private/ {print $3}')"
......@@ -43,12 +76,16 @@ KEYS="$(programs/eosc/eosc create key)"
verifyErrorCode "eosc create key"
PRV_KEY2="$(echo "$KEYS" | awk '/Private/ {print $3}')"
PUB_KEY2="$(echo "$KEYS" | awk '/Public/ {print $3}')"
if [ -z "$PRV_KEY1" ] || [ -z "$PRV_KEY2" ] || [ -z "$PUB_KEY1" ] || [ -z "$PUB_KEY2" ]; then
KEYS="$(programs/eosc/eosc create key)"
verifyErrorCode "eosc create key"
PRV_KEY3="$(echo "$KEYS" | awk '/Private/ {print $3}')"
PUB_KEY3="$(echo "$KEYS" | awk '/Public/ {print $3}')"
if [ -z "$PRV_KEY1" ] || [ -z "$PRV_KEY2" ] || [ -z "$PRV_KEY3" ] || [ -z "$PUB_KEY1" ] || [ -z "$PUB_KEY2" ] || [ -z "$PUB_KEY3" ]; then
error "FAILURE - create keys"
fi
# walletd
programs/eos-walletd/eos-walletd --data-dir tn_wallet_0 --http-server-endpoint=127.0.0.1:8899 > test_walletd_output.log 2>&1 &
programs/eos-walletd/eos-walletd --data-dir test_wallet_0 --http-server-endpoint=127.0.0.1:8899 > test_walletd_output.log 2>&1 &
verifyErrorCode "eos-walletd"
WALLETD_PROC_ID=$!
sleep 3
......@@ -56,43 +93,208 @@ sleep 3
# import into a wallet
PASSWORD="$(programs/eosc/eosc --wallet-port 8899 wallet create --name test)"
verifyErrorCode "eosc wallet create"
# strip out password from output
PASSWORD="$(echo "$PASSWORD" | awk '/PW/ {print $1}')"
# remove leading/trailing quotes
PASSWORD=${PASSWORD#\"}
PASSWORD=${PASSWORD%\"}
programs/eosc/eosc --wallet-port 8899 wallet import --name test $PRV_KEY1
verifyErrorCode "eosc wallet import"
programs/eosc/eosc --wallet-port 8899 wallet import --name test $PRV_KEY2
verifyErrorCode "eosc wallet import"
programs/eosc/eosc --wallet-port 8899 wallet import --name test $INITA_PRV_KEY
programs/eosc/eosc --wallet-port 8899 wallet import --name test $PRV_KEY3
verifyErrorCode "eosc wallet import"
# create wallet for inita
PASSWORD_INITA="$(programs/eosc/eosc --wallet-port 8899 wallet create --name inita)"
verifyErrorCode "eosc wallet create"
# strip out password from output
PASSWORD_INITA="$(echo "$PASSWORD_INITA" | awk '/PW/ {print $1}')"
# remove leading/trailing quotes
PASSWORD_INITA=${PASSWORD_INITA#\"}
PASSWORD_INITA=${PASSWORD_INITA%\"}
programs/eosc/eosc --wallet-port 8899 wallet import --name inita $INITA_PRV_KEY
verifyErrorCode "eosc wallet import"
# lock wallet
programs/eosc/eosc --wallet-port 8899 wallet lock --name test
verifyErrorCode "eosc wallet lock"
# unlock wallet
echo $PASSWORD | programs/eosc/eosc --wallet-port 8899 wallet unlock --name test
verifyErrorCode "eosc wallet unlock"
# lock via lock_all
programs/eosc/eosc --wallet-port 8899 wallet lock_all
verifyErrorCode "eosc wallet lock_all"
# unlock wallet again
echo $PASSWORD | programs/eosc/eosc --wallet-port 8899 wallet unlock --name test
verifyErrorCode "eosc wallet unlock"
# wallet list
OUTPUT=$(programs/eosc/eosc --wallet-port 8899 wallet list)
verifyErrorCode "eosc wallet list"
count=`echo $OUTPUT | grep "test" | grep -c "\*"`
if [[ $count == 0 ]]; then
error "FAILURE - wallet list did not include \*"
fi
# wallet keys
OUTPUT=$(programs/eosc/eosc --wallet-port 8899 wallet keys)
verifyErrorCode "eosc wallet keys"
count=`echo $OUTPUT | grep -c "$PRV_KEY1"`
if [[ $count == 0 ]]; then
error "FAILURE - wallet keys did not include $PRV_KEY1"
fi
count=`echo $OUTPUT | grep -c "$PRV_KEY2"`
if [[ $count == 0 ]]; then
error "FAILURE - wallet keys did not include $PRV_KEY2"
fi
# lock via lock_all
programs/eosc/eosc --wallet-port 8899 wallet lock_all
verifyErrorCode "eosc wallet lock_all"
# unlock wallet inita
echo $PASSWORD_INITA | programs/eosc/eosc --wallet-port 8899 wallet unlock --name inita
verifyErrorCode "eosc wallet unlock inita"
OUTPUT=$(programs/eosc/eosc --wallet-port 8899 wallet keys)
count=`echo $OUTPUT | grep -c "$INITA_PRV_KEY"`
if [[ $count == 0 ]]; then
error "FAILURE - wallet keys did not include $INITA_PRV_KEY"
fi
# create new account
programs/eosc/eosc --wallet-port 8899 create account inita tester $PUB_KEY1 $PUB_KEY2
ACCOUNT_INFO="$(programs/eosc/eosc --wallet-port 8899 create account inita testera $PUB_KEY1 $PUB_KEY3)"
verifyErrorCode "eosc create account"
waitForNextBlock
# verify account created
ACCOUNT_INFO="$(programs/eosc/eosc --wallet-port 8899 get account tester)"
ACCOUNT_INFO="$(programs/eosc/eosc --wallet-port 8899 get account testera)"
verifyErrorCode "eosc get account"
count=`echo $ACCOUNT_INFO | grep -c "exception"`
if [ $count != 0 ]; then
error "FAILURE - account creation caused exception: $ACCOUNT_INFO"
fi
count=`echo $ACCOUNT_INFO | grep -c "staked_balance"`
if [ $count == 0 ]; then
error "FAILURE - account creation failed: $ACCOUNT_INFO"
fi
# transfer
programs/eosc/eosc --wallet-port 8899 transfer inita tester 975321 "test transfer"
TRANSFER_INFO="$(programs/eosc/eosc --wallet-port 8899 transfer inita testera 975321 "test transfer")"
verifyErrorCode "eosc transfer"
# verify transfer
ACCOUNT_INFO="$(programs/eosc/eosc --wallet-port 8899 get account tester)"
count=`echo $ACCOUNT_INFO | grep -c "exception"`
if [ $count != 0 ]; then
error "FAILURE - transfer caused exception: $ACCOUNT_INFO"
fi
ACCOUNT_INFO="$(programs/eosc/eosc --wallet-port 8899 get account testera)"
count=`echo $ACCOUNT_INFO | grep -c "97.5321"`
if [ $count == 0 ]; then
error "FAILURE - transfer failed: $ACCOUNT_INFO"
fi
# create another new account via initb
ACCOUNT_INFO="$(programs/eosc/eosc --wallet-port 8899 create account initb testerb $PUB_KEY2 $PUB_KEY3)"
verifyErrorCode "eosc create account"
waitForNextBlock
#
# now transfer from testera to testerb using keys from testera
#
# lock via lock_all
programs/eosc/eosc --wallet-port 8899 wallet lock_all
verifyErrorCode "eosc wallet lock_all"
# unlock wallet
echo $PASSWORD | programs/eosc/eosc --wallet-port 8899 wallet unlock --name test
verifyErrorCode "eosc wallet unlock"
# transfer
TRANSFER_INFO="$(programs/eosc/eosc --wallet-port 8899 transfer testera testerb 975311 "test transfer a->b")"
verifyErrorCode "eosc transfer"
TRANS_ID="$(echo "$TRANSFER_INFO" | awk '/transaction_id/ {print $2}')"
waitForNextBlock
# remove leading/trailing quotes
TRANS_ID=${TRANS_ID#\"}
TRANS_ID=${TRANS_ID%\",}
# verify transfer
ACCOUNT_INFO="$(programs/eosc/eosc --wallet-port 8899 get account testerb)"
verifyErrorCode "eosc get account testerb"
count=`echo $ACCOUNT_INFO | grep -c "97.5311"`
if [ $count == 0 ]; then
error "FAILURE - transfer failed: $ACCOUNT_INFO"
fi
# get accounts via public key
ACCOUNT_INFO="$(programs/eosc/eosc --wallet-port 8899 get accounts $PUB_KEY3)"
verifyErrorCode "eosc get accounts pub_key3"
count=`echo $ACCOUNT_INFO | grep -c "testera"`
if [ $count == 0 ]; then
error "FAILURE - get accounts failed: $ACCOUNT_INFO"
fi
count=`echo $ACCOUNT_INFO | grep -c "testerb"`
if [ $count == 0 ]; then
error "FAILURE - get accounts failed: $ACCOUNT_INFO"
fi
ACCOUNT_INFO="$(programs/eosc/eosc --wallet-port 8899 get accounts $PUB_KEY1)"
verifyErrorCode "eosc get accounts pub_key1"
count=`echo $ACCOUNT_INFO | grep -c "testera"`
if [ $count == 0 ]; then
error "FAILURE - get accounts failed: $ACCOUNT_INFO"
fi
count=`echo $ACCOUNT_INFO | grep -c "testerb"`
if [ $count != 0 ]; then
error "FAILURE - get accounts failed: $ACCOUNT_INFO"
fi
# get servant accounts
ACCOUNT_INFO="$(programs/eosc/eosc --wallet-port 8899 get servants inita)"
verifyErrorCode "eosc get servants inita"
count=`echo $ACCOUNT_INFO | grep -c "testera"`
if [ $count == 0 ]; then
error "FAILURE - get servants failed: $ACCOUNT_INFO"
fi
count=`echo $ACCOUNT_INFO | grep -c "testerb"`
if [ $count != 0 ]; then
error "FAILURE - get servants failed: $ACCOUNT_INFO"
fi
ACCOUNT_INFO="$(programs/eosc/eosc --wallet-port 8899 get servants testera)"
verifyErrorCode "eosc get servants testera"
count=`echo $ACCOUNT_INFO | grep -c "testera"`
if [ $count != 0 ]; then
error "FAILURE - get servants failed: $ACCOUNT_INFO"
fi
# get transaction
TRANS_INFO="$(programs/eosc/eosc --wallet-port 8899 get transaction $TRANS_ID)"
verifyErrorCode "eosc get transaction trans_id"
count=`echo $TRANS_INFO | grep -c "transfer"`
if [ $count == 0 ]; then
error "FAILURE - get transaction trans_id failed: $TRANS_INFO"
fi
count=`echo $TRANS_INFO | grep -c "975311"`
if [ $count == 0 ]; then
error "FAILURE - get transaction trans_id failed: $TRANS_INFO"
fi
# get transactions
TRANS_INFO="$(programs/eosc/eosc --wallet-port 8899 get transactions testera)"
verifyErrorCode "eosc get transactions testera"
count=`echo $TRANS_INFO | grep -c "$TRANS_ID"`
if [ $count == 0 ]; then
error "FAILURE - get transactions testera failed: $TRANS_INFO"
fi
# should be able to get every block from beginning to end
getHeadBlockNum
CURRENT_BLOCK_NUM=$HEAD_BLOCK_NUM
NEXT_BLOCK_NUM=1
while [ "$NEXT_BLOCK_NUM" -le "$HEAD_BLOCK_NUM" ]; do
INFO="$(programs/eosc/eosc get block $NEXT_BLOCK_NUM)"
verifyErrorCode "eosc get block"
NEXT_BLOCK_NUM=$((NEXT_BLOCK_NUM+1))
done
killAll
cleanup
echo SUCCESS!
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册