提交 73a41588 编写于 作者: D Daniel Larimer 提交者: GitHub

Merge pull request #415 from pavybez/master

Implementation of scripts for issue 246
......@@ -175,6 +175,7 @@ add_subdirectory( libraries )
add_subdirectory( programs )
add_subdirectory( plugins )
add_subdirectory( tests )
add_subdirectory( tools )
if (ENABLE_INSTALLER)
......
......@@ -22,8 +22,9 @@ develop applications (smart contracts).
1. [Getting Started](#gettingstarted)
2. [Setting up a build/development environment](#setup)
1. [Clean install Ubuntu 16.10](#ubuntu)
2. [macOS Sierra 10.12.6](#macos)
1. [Automated build script](#autobuild)
2. [Clean install Ubuntu 16.10](#ubuntu)
3. [macOS Sierra 10.12.6](#macos)
3. [Building EOS and running a node](#runanode)
1. [Getting the code](#getcode)
2. [Building from source code](#build)
......@@ -58,6 +59,22 @@ Dependencies:
* [secp256k1-zkp (Cryptonomex branch)](https://github.com/cryptonomex/secp256k1-zkp.git)
* [binaryen](https://github.com/WebAssembly/binaryen.git)
<a name="autobuild"></a>
### Automated build script
For Ubuntu 16.10 and macOS Sierra, there is an automated build script that can install all dependencies and builds EOS.
Clone EOS repository recursively as below and run build.sh located in root `eos` folder:
```bash
git clone https://github.com/eosio/eos --recursive
cd eos
./build.sh ubuntu # For ubuntu
./build.sh darwin # For macOS
```
<a name="ubuntu"></a>
### Clean install Ubuntu 16.10
......
#!/usr/bin/env bash
##########################################################################
# This is EOS bootstrapper script for Linux and OS X.
# This file was downloaded from https://github.com/EOSIO/eos
# Feel free to change this file to fit your needs.
##########################################################################
VERSION=1.0
# Define directories.
WORK_DIR=$PWD
BUILD_DIR=${WORK_DIR}/build
TEMP_DIR=/tmp
BINARYEN_BIN=/opt/binaryen/bin/
OPENSSL_ROOT_DIR=/usr/local/opt/openssl
OPENSSL_LIBRARIES=/usr/local/opt/openssl/lib
WASM_LLVM_CONFIG=/opt/wasm/bin/llvm-config
# Target architectures
ARCH=$1
TARGET_ARCHS="ubuntu darwin"
# Check ARCH
if [[ $# > 1 ]]; then
echo ""
echo "Error: too many arguments"
exit 1
fi
if [[ $# < 1 ]]; then
echo ""
echo "Usage: bash build.sh TARGET"
echo ""
echo "Targets: $TARGET_ARCHS"
exit 1
fi
if [[ $ARCH =~ [[:space:]] || ! $TARGET_ARCHS =~ (^|[[:space:]])$ARCH([[:space:]]|$) ]]; then
echo ""
echo ">>> WRONG ARCHITECTURE \"$ARCH\""
exit 1
fi
echo ""
echo ">>> ARCHITECTURE \"$ARCH\""
# Debug flags
INSTALL_DEPS=1
COMPILE_EOS=1
COMPILE_CONTRACTS=1
# Define default arguments.
CMAKE_BUILD_TYPE=Debug
# Install dependencies
if [ ${INSTALL_DEPS} == "1" ]; then
print ">> Install dependencies"
. ${WORK_DIR}/scripts/install_dependencies.sh
fi
# Create the build dir
cd ${WORK_DIR}
mkdir -p ${BUILD_DIR}
cd ${BUILD_DIR}
# Build EOS
cmake -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DWASM_LLVM_CONFIG=${WASM_LLVM_CONFIG} -DBINARYEN_BIN=${BINARYEN_BIN} -DOPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR} -DOPENSSL_LIBRARIES=${OPENSSL_LIBRARIES} ..
make -j4
\ No newline at end of file
{
"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",
"type": "account",
"indextype": "i64",
"keynames" : ["account"],
"keytypes" : ["Name"]
}
]
}
#include <currency/currency.hpp> /// defines transfer struct (abi)
namespace TOKEN_NAME {
using namespace eos;
/// When storing accounts, check for empty balance and remove account
void storeAccount( AccountName account, const Account& a ) {
if( a.isEmpty() ) {
/// value, scope
Accounts::remove( a, account );
} else {
/// value, scope
Accounts::store( a, account );
}
}
void apply_currency_transfer( const TOKEN_NAME::Transfer& transfer ) {
requireNotice( transfer.to, transfer.from );
requireAuth( transfer.from );
auto from = getAccount( transfer.from );
auto to = getAccount( transfer.to );
from.balance -= transfer.quantity; /// token subtraction has underflow assertion
to.balance += transfer.quantity; /// token addition has overflow assertion
storeAccount( transfer.from, from );
storeAccount( transfer.to, to );
}
} // namespace TOKEN_NAME
using namespace currency;
extern "C" {
void init() {
storeAccount( N(currency), Account( CurrencyTokens(1000ll*1000ll*1000ll) ) );
}
/// The apply method implements the dispatch of events to this contract
void apply( uint64_t code, uint64_t action ) {
if( code == N(currency) ) {
if( action == N(transfer) )
currency::apply_currency_transfer( currentMessage< TOKEN_NAME::Transfer >() );
}
}
}
#include <eoslib/eos.hpp>
#include <eoslib/token.hpp>
#include <eoslib/db.hpp>
/**
* Make it easy to change the account name the currency is deployed to.
*/
#ifndef TOKEN_NAME
#define TOKEN_NAME currency
#endif
namespace TOKEN_NAME {
/**
* @defgroup currencyapi Currency Contract API
* @brief Defines the curency contract
* @ingroup contractapi
*
* @{
*/
/**
* Defines a currency token
*/
typedef eos::token<uint64_t,N(currency)> CurrencyTokens;
/**
* Transfer requires that the sender and receiver be the first two
* accounts notified and that the sender has provided authorization.
*/
struct Transfer {
/**
* Account to transfer from
*/
AccountName from;
/**
* Account to transfer to
*/
AccountName to;
/**
* quantity to transfer
*/
CurrencyTokens quantity;
};
/**
* @brief row in Account table stored within each scope
*/
struct Account {
/**
Constructor with default zero quantity (balance).
*/
Account( CurrencyTokens b = CurrencyTokens() ):balance(b){}
/**
* The key is constant because there is only one record per scope/currency/accounts
*/
const uint64_t key = N(account);
/**
* Balance number of tokens in account
**/
CurrencyTokens balance;
/**
Method to check if accoutn is empty.
@return true if account balance is zero.
**/
bool isEmpty()const { return balance.quantity == 0; }
};
/**
Assert statement to verify structure packing for Account
**/
static_assert( sizeof(Account) == sizeof(uint64_t)+sizeof(CurrencyTokens), "unexpected packing" );
/**
Defines the database table for Account information
**/
using Accounts = Table<N(currency),N(currency),N(account),Account,uint64_t>;
/**
* Accounts information for owner is stored:
*
* owner/TOKEN_NAME/account/account -> Account
*
* This API is made available for 3rd parties wanting read access to
* the users balance. If the account doesn't exist a default constructed
* account will be returned.
* @param owner The account owner
* @return Account instance
*/
inline Account getAccount( AccountName owner ) {
Account account;
/// scope, record
Accounts::get( account, owner );
return account;
}
} /// @} /// currencyapi
# Install dependencies script
if [ $ARCH == "ubuntu" ]; then
# install dev toolkit
sudo apt-get update
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
sudo apt-get install clang-4.0 lldb-4.0 cmake make \
libbz2-dev libssl-dev libgmp3-dev \
autotools-dev build-essential \
libbz2-dev libicu-dev python-dev \
autoconf libtool git
OPENSSL_ROOT_DIR=/usr/local/opt/openssl
OPENSSL_LIBRARIES=/usr/local/opt/openssl/lib
# install boost
cd ${TEMP_DIR}
export BOOST_ROOT=${HOME}/opt/boost_1_64_0
curl -L https://sourceforge.net/projects/boost/files/boost/1.64.0/boost_1_64_0.tar.bz2 > boost_1.64.0.tar.bz2
tar xvf boost_1.64.0.tar.bz2
cd boost_1_64_0/
./bootstrap.sh "--prefix=$BOOST_ROOT"
./b2 install
rm -rf ${TEMP_DIR}/boost_1_64_0/
# install secp256k1-zkp (Cryptonomex branch)
cd ${TEMP_DIR}
git clone https://github.com/cryptonomex/secp256k1-zkp.git
cd secp256k1-zkp
./autogen.sh
./configure
make
sudo make install
rm -rf cd ${TEMP_DIR}/secp256k1-zkp
# install binaryen
cd ${TEMP_DIR}
git clone https://github.com/WebAssembly/binaryen
cd binaryen
git checkout tags/1.37.14
cmake . && make
mkdir -p ${HOME}/opt/binaryen/
mv ${TEMP_DIR}/binaryen/bin ${HOME}/opt/binaryen/
rm -rf ${TEMP_DIR}/binaryen
BINARYEN_BIN=${HOME}/opt/binaryen/bin
# build llvm with wasm build target:
cd ${TEMP_DIR}
mkdir wasm-compiler
cd wasm-compiler
git clone --depth 1 --single-branch --branch release_40 https://github.com/llvm-mirror/llvm.git
cd llvm/tools
git clone --depth 1 --single-branch --branch release_40 https://github.com/llvm-mirror/clang.git
cd ..
mkdir build
cd build
cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=${HOME}/opt/wasm -DLLVM_TARGETS_TO_BUILD= -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly -DCMAKE_BUILD_TYPE=Release ../
make -j4 install
rm -rf ${TEMP_DIR}/wasm-compiler
WASM_LLVM_CONFIG=${HOME}/opt/wasm/bin/llvm-config
fi
if [ $ARCH == "darwin" ]; then
DEPS="git automake libtool boost openssl llvm@4 gmp wget"
brew update
brew install --force $DEPS
brew unlink $DEPS && brew link --force $DEPS
# LLVM_DIR=/usr/local/Cellar/llvm/4.0.1/lib/cmake/llvm
# install secp256k1-zkp (Cryptonomex branch)
cd ${TEMP_DIR}
git clone https://github.com/cryptonomex/secp256k1-zkp.git
cd secp256k1-zkp
./autogen.sh
./configure
make
sudo make install
rm -rf cd ${TEMP_DIR}/secp256k1-zkp
# Install binaryen v1.37.14:
cd ${TEMP_DIR}
git clone https://github.com/WebAssembly/binaryen
cd binaryen
git checkout tags/1.37.14
cmake . && make
mkdir /usr/local/binaryen
mv ${TEMP_DIR}/binaryen/bin /usr/local/binaryen
ln -s /usr/local/binaryen/bin/* /usr/local
rm -rf ${TEMP_DIR}/binaryen
BINARYEN_BIN=/usr/local/binaryen/bin/
# Build LLVM and clang for WASM:
cd ${TEMP_DIR}
mkdir wasm-compiler
cd wasm-compiler
git clone --depth 1 --single-branch --branch release_40 https://github.com/llvm-mirror/llvm.git
cd llvm/tools
git clone --depth 1 --single-branch --branch release_40 https://github.com/llvm-mirror/clang.git
cd ..
mkdir build
cd build
cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=/usr/local/wasm -DLLVM_TARGETS_TO_BUILD= -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly -DCMAKE_BUILD_TYPE=Release ../
make -j4 install
rm -rf ${TEMP_DIR}/wasm-compiler
WASM_LLVM_CONFIG=/usr/local/wasm/bin/llvm-config
fi
\ No newline at end of file
configure_file("eoscpp" "${CMAKE_CURRENT_BINARY_DIR}" @ONLY)
#!/bin/bash -e
function copy_skeleton {
cp -r @CMAKE_SOURCE_DIR@/contracts/skeleton/. $newname
for file in $(find ./$newname -name 'skeleton.*')
do
mv "${file}" "`echo $file | sed 's/skeleton\./'"$newname"'./'`"
done
echo "skeleton $newname contract created"
}
function build_contract {
workdir=`mktemp -d`
mkdir $workdir/built
for file in $@; do
name=`basename $file`
filePath=`dirname $file`
@WASM_CLANG@ -emit-llvm -O3 --std=c++14 --target=wasm32 -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -I @CMAKE_SOURCE_DIR@/contracts -I $filePath -c $file -o $workdir/built/$name
done
@WASM_LLVM_LINK@ -o $workdir/linked.bc $workdir/built/*
@WASM_LLC@ --asm-verbose=false -o $workdir/assembly.s $workdir/linked.bc
@BINARYEN_BIN@/s2wasm -o $outname -s 16384 $workdir/assembly.s
rm -rf $workdir
}
function print_help {
echo "Usage: $0 -o output.wast contract.cpp [other.cpp ...]"
echo " OR"
echo " $0 -n mycontract"
echo
echo "Options:"
echo " -n | --newcontract [name]"
echo " Create a new contract in the [name] folder, based on the example contract"
echo " OR"
echo " -o | --outname [output.wast] [input.cpp ...]"
echo " Generate the wast output file based on input cpp files"
}
command=""
while [[ $# -gt 1 ]]
do
key="$1"
case $key in
-n|--newcontract)
newname="$2"
command="newcontract"
shift 2
;;
-h|--help)
print_help
;;
-o|--outname)
outname="$2"
command="outname"
shift 2
break
;;
*)
echo "Unrecognized option: $1"
exit 1
;;
esac
done
if [[ "outname" == "$command" ]]; then
build_contract $@
else
if [[ "newcontract" == "$command" ]]; then
copy_skeleton
else
print_help
exit 1
fi
fi
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册