Giter Site home page Giter Site logo

learnforpractice / pyeos Goto Github PK

View Code? Open in Web Editor NEW
133.0 24.0 37.0 128.43 MB

A Universal Smart Contract Platform

License: MIT License

CMake 2.44% Shell 0.83% C++ 53.42% C 2.17% Python 4.97% WebAssembly 32.43% Perl 0.05% Thrift 0.02% Go 1.76% Makefile 1.75% Dockerfile 0.03% Objective-C 0.01% Julia 0.01% Lua 0.04% Java 0.08%
python eos ethereum

pyeos's Introduction

A Self Evolving Universal Smart Contract Platform Base on The Development of EOSIO

Table of contents

  1. Building PyEos

  2. Smart Contract Development

    2.1 Python Smart Contract Development

    2.2 Ethereum Smart Contract Development

    2.3 Lua Smart Contract Development

    2.4 Java Smart Contract Development

  3. Debugging With C++ Smart Contract

  4. Debugging With Python Smart Contract

  5. PyEos API overview

Building PyEos

Downloading Source Code

git clone https://www.github.com/learnforpractice/pyeos
cd pyeos
git submodule update --init --recursive

Installing dependencies (Ubuntu)

sudo apt-get install libleveldb-dev
sudo apt-get install libreadline-dev

Installing dependencies (Centos)

sudo yum install leveldb-devel
sudo yum install readline-devel
sudo yum install libffi-devel

Installing dependencies (macOS)

brew install leveldb
brew install readline

Installing JDK 10 or above (Optional)

For those who want to try Java Smart Contract, please update JDK to version 10 or above, then export JAVA_HOME to the root directory of JDK install directory.

export JAVA_HOME=<directory of jdk>

If you have earlier JDK installed and JAVA_HOME is not empty and you don't want to try Java smart contract, please empty JAVA_HOME with the following command before building:

export JAVA_HOME=

Building

./eosio_build.sh

Smart Contract Development

Python Smart Contract Development

Running PyEos

Open a terminal, cd to [PROJECT_DIR]/build/program, run the following command

./pyeos/pyeos --manual-gen-block --debug -i  --contracts-console

If this is the first time you start PyEos, PyEos will create a testing wallet for you, which placed in data-dir/mywallet.wallet, and then console will print the wallet password as below:

wallet password: PW5JWE5g6RZ7Fyr2kmCphDqZo4uivdeGpUpndgFZ52rsduhtf9PRJ

Since it's for testing only, password will save to data-dir/data.pkl, So next time you start pyeos for testing, pyeos will unlock wallet for you.

Also PyEos will import three private keys to the wallet, which is useful for testing.

'5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3',
'5JEcwbckBCdmji5j8ZoMHLEUS8TqQiqBG1DRx1X9DN124GUok9s',
'5JbDP55GXN7MLcNYKCnJtfKi9aD2HvHAdY7g8m67zFTAFkY1uBB'

Keep in mind that these private keys should never be used in real account, otherwise you may lose all of your crypto property in the account.

Beside that, PyEos will create four important accounts for you:

eosio.bios, eosio.msig, eosio.system, eosio.token

and publish their smart contract on testnet.

Although the above steps will never happen in the real world, but it's really provide a great convenience for testing smart contract. Thus save a lot of your precious time and make the development more efficient.

Generating source code with sketch tool

Run the following command in PyEos console,

sketch.create('hello', 'helloworld', 'py')

That will create a helloworld directory under your current directory with hello as the testing account name. There are three file generated in the directory:

helloworld.py
helloworld.abi
t.py

Which helloworld.py is the Python smart contract source code, helloworld.abi is the ABI(Application Binary Interface) file for smart contract, t.py contains code for testing smart contract.

In addition, sketch can also create a wasm smart contract project for you, just type the following code in PyEos console, and the testing process has no difference with Python smart contract.

sketch.create('helloworld', 'helloworld', 'cpp')

Testing

Now it's time to run your helloworld smart contract program. Type or copy the following command to the PyEos console:

from helloworld import t
t.test()

You will see the following output on console in green words:

3289633ms thread-1   mpeoslib.cpp:63               print                ] hello,world

Congratulations, you have successfully run your first Python smart contract.

Now you can open helloworld.py for coding. Once it's done, just run t.test() again, there is no need to run other command to publish your testing smart contract, the smart contract will be automatically republish to the testnet if it's been changed during the running of t.test(). You can also edit the testing code in t.py for testing your smart contract. Once it's done, just run t.test() again, there is no need to run reload(t), PyEos will do the magic for you. That also works at the situation of adding a new function in test.

Ethereum Smart Contract Development

Please see the example in pyeos/programs/pyeos/tests/evm/evm

Lua Smart Contract Development

Please see the example in pyeos/programs/pyeos/tests/lua/hello

Java Smart Contract Development

Please see the example in pyeos/programs/pyeos/tests/java/hello

Reminder: For these who want to try Java Smart Contract, please update JDK to version 10 or above, and then set JAVA_HOME to the appropriate JDK root directory

Debugging With C++ Smart Contract

On Eos, C++ Smart Contract code is compiled to WebAssembly bytecode, that makes debugging C++ Smart Contract suffer. Fortunately now it's able to compile C++ Smart Contract to a shared library, that makes debugging a C++ Smart Contract as easy as debugging a normal C++ project.

There is a short video on youtube for quick start:

Debugging

To be brief, here are the steps about debugging a C++ Smart Contract:

1. Open pyeos project in Visual Studio Code

2. Edit CMAKE_BUILD_TYPE and BUILD_DIR in eosio_build.sh

    BUILD_DIR="${PWD}/build-debug"
    CMAKE_BUILD_TYPE=Debug

3. Build pyeos in VSC terminal

./eosio_build.sh

4.Configure debug in Visual Studio Code

      {
         "name": "(lldb) Attach pyeos",
         "type": "cppdbg",
         "request": "attach",
         "program": "${workspaceFolder}/build-debug/programs/pyeos/pyeos",
         "processId": "${command:pickProcess}",
         "MIMode": "lldb"
      }

5. Launch pyeos

./pyeos/pyeos --manual-gen-block --debug -i  --contracts-console

6. Attach to pyeos

7. Create C++ Smart Contract test code.

sketch.create('hello', 'helloworld', 'cpp')

8. Set breakpoint in test code

9. Testing

from helloworld import t
t.debug()

Python Smart Contract Debugging

There is a short video on youtube about Python Smart Contract for quick start:

Debugging

The following steps show how to debug smart contract under programs/pyeos/contracts/hello

1. Launch PyEos

./pyeos/pyeos --manual-gen-block --debug -i  --contracts-console

2. Set debug contract

debug.set_debug_contract('hello', '../../programs/pyeos/contracts/hello/hello.py')

3. Start ptvsd debugger

import ptvsd
ptvsd.enable_attach("12345", address = ('127.0.0.1', 3000))
ptvsd.wait_for_attach()

4. Attach to ptvsd debugger in Visual Studio Code

Here is the debug setting:

   {
      "name": "python Attach (Remote Debug)",
      "type": "python",
      "request": "attach",
      "localRoot": "${workspaceFolder}",
      "remoteRoot": "${workspaceFolder}",
      "port": 3000,
      "secret": "12345",
      "host": "localhost"
   },

5. Set breakpoint in hello.py

6. Debugging

from hello import t
t.test()

Enjoy it!

PyEos API overview

eosapi.get_info

info = eosapi.get_info()
info
{
    "server_version": "00000000",
    "head_block_num": 127,
    "last_irreversible_block_num": 126,
    "head_block_id": "0000007fbd1ff82f29668dfa89d927a0510c657cce292c033496ccaacf04c12a",
    "head_block_time": "2018-05-06T07:57:44",
    "head_block_producer": "eosio"
}
info.head_block_time
'2017-09-23T15:16:18'
info.head_block_num
18624

wallet.create

PyEos will create a testing wallet for you the first time you start it, but you can also create other wallet wit wallet.create API

psw = wallet.create('mywallet2')
psw
'PW5JCWXaGkA15s6th6AWCabHewuGASAtrUJjTWoL1Ybx6sG9QzrSb'

You can see your wallet now. The * behind mywallet means the wallet is unlocked.

wallet.list_wallets()
['mywallet *']

wallet.open wallet.unlock

wallet.open('mywallet2')
wallet.unlock('mywallet2','PW5JCWXaGkA15s6th6AWCabHewuGASAtrUJjTWoL1Ybx6sG9QzrSb')

wallet.import_key

Let's import the private key of inita. Please refer to Setting up a wallet and importing account key for more information.

wallet.import_key('mywallet2','5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3')

eosapi.create_key

Create owner key

eosapi.create_key()
{'public': 'EOS61MgZLN7Frbc2J7giU7JdYjy2TqnfWFjZuLXvpHJoKzWAj7Nst', 'private': '5JEcwbckBCdmji5j8ZoMHLEUS8TqQiqBG1DRx1X9DN124GUok9s'}

Create active key

eosapi.create_key()
{'public': 'EOS5JuNfuZPATy8oPz9KMZV2asKf9m8fb2bSzftvhW55FKQFakzFL', 'private': '5JbDP55GXN7MLcNYKCnJtfKi9aD2HvHAdY7g8m67zFTAFkY1uBB'}

Import owner key

wallet.import_key('mywallet2','5JEcwbckBCdmji5j8ZoMHLEUS8TqQiqBG1DRx1X9DN124GUok9s')

Import active key

wallet.import_key('mywallet2','5JbDP55GXN7MLcNYKCnJtfKi9aD2HvHAdY7g8m67zFTAFkY1uBB')

eosapi.create_account

key1 = 'EOS61MgZLN7Frbc2J7giU7JdYjy2TqnfWFjZuLXvpHJoKzWAj7Nst'
key2 = 'EOS5JuNfuZPATy8oPz9KMZV2asKf9m8fb2bSzftvhW55FKQFakzFL'
eosapi.create_account('eosio', 'currency', key1, key2)

eosapi.get_account

eosapi.get_account('currency')
{
    "account_name": "currency",
    "head_block_num": 43,
    "head_block_time": "2018-07-11T09:01:00.500",
    "privileged": false,
    "last_code_update": "1970-01-01T00:00:00.000",
    "created": "2018-07-11T09:01:00.500",
    "ram_quota": 65206,
    "net_weight": 10050,
    "cpu_weight": 10050,
    "net_limit": {
        "used": 0,
        "available": 62988768000,
        "max": 62988768000
    },
    "cpu_limit": {
        "used": 0,
        "available": 12013286400,
        "max": 12013286400
    },
    "ram_usage": 3446,
    "permissions": [
        {
            "perm_name": "active",
            "parent": "owner",
            "required_auth": {
                "threshold": 1,
                "keys": [
                    {
                        "key": "EOS61MgZLN7Frbc2J7giU7JdYjy2TqnfWFjZuLXvpHJoKzWAj7Nst",
                        "weight": 1
                    }
                ],
                "accounts": [],
                "waits": []
            }
        },
        {
            "perm_name": "owner",
            "parent": "",
            "required_auth": {
                "threshold": 1,
                "keys": [
                    {
                        "key": "EOS5JuNfuZPATy8oPz9KMZV2asKf9m8fb2bSzftvhW55FKQFakzFL",
                        "weight": 1
                    }
                ],
                "accounts": [],
                "waits": []
            }
        }
    ],
    "total_resources": {
        "owner": "currency",
        "net_weight": "1.0050 EOS",
        "cpu_weight": "1.0050 EOS",
        "ram_bytes": 65206
    },
    "self_delegated_bandwidth": {
        "from": "currency",
        "to": "currency",
        "net_weight": "1.0050 EOS",
        "cpu_weight": "1.0050 EOS"
    },
    "refund_request": null,
    "voter_info": {
        "owner": "currency",
        "proxy": "",
        "producers": [],
        "staked": 20100,
        "last_vote_weight": 0.0,
        "proxied_vote_weight": 0.0,
        "is_proxy": 0
    }
}

eosapi.get_balance

eosapi.get_balance('eosio')

return:

9999999961645.494

eosapi.transfer

eosapi.transfer('eosio', 'currency', 100.6666)

return:

True

eosapi.push_action

eosapi.get_balance('eosio')
eosapi.get_balance('currency')
args = {"from":'eosio', "to":'currency', "quantity":'100.6666 EOS', "memo":'hello'}
r = eosapi.push_action('eosio.token', 'transfer', args, {'eosio':'active'})
eosapi.get_balance('eosio')
eosapi.get_balance('currency')
>>> eosapi.get_balance('eosio')
9999999961142.162
>>> eosapi.get_balance('currency')
513.9996
>>> args = {"from":'eosio', "to":'currency', "quantity":'100.6666 EOS', "memo":'hello'}
>>> r = eosapi.push_action('eosio.token', 'transfer', args, {'eosio':'active'})
>>> eosapi.get_balance('eosio')
9999999961041.496
>>> eosapi.get_balance('currency')
614.6662

the above code is what eosapi.transfer does.

eosapi.push_actions

r = get_balance('currency')
print(r)
args = {"from":'eosio', "to":'currency', "quantity":'100.6666 EOS', "memo":'hello'}
args = eosapi.pack_args('eosio.token', 'transfer', args)
act = ['eosio.token', 'transfer', {'eosio':'active'}, args]
r = eosapi.push_actions([act, act])
r = eosapi.get_balance('currency')
print(r)
>>> r = get_balance('currency')
>>> print(r)
211.9998
>>> args = {"from":'eosio', "to":'currency', "quantity":'100.6666 EOS', "memo":'hello'}
>>> args = eosapi.pack_args('eosio.token', 'transfer', args)
>>> act = ['eosio.token', 'transfer', {'eosio':'active'}, args]
>>> r = eosapi.push_actions([act, act])
>>> r = eosapi.get_balance('currency')
>>> print(r)
413.333

eosapi.get_transaction

r = eosapi.get_transaction('f6c43148dfac54105031fbaf966958d36309dd94e665c506eb2769e43febedba')
r
r.transaction.signatures
r.transaction.packed_trx

eosapi.set_contract

Publish python smart contract to the blockchain

r = eosapi.set_contract('hello','../../programs/pyeos/contracts/hello/hello.py','../../contracts/hello/hello.abi',1)
r

pyeos's People

Contributors

andrewscheidecker avatar andriantolie avatar arhag avatar asiniscalchi avatar b1bart avatar brianjohnson5972 avatar bytemaster avatar cj-oci avatar dskvr avatar elmato avatar ericiles avatar heifner avatar jgiszczak avatar kesar avatar larryk85 avatar learnforpractice avatar mitza-oci avatar moskvanaft avatar nathanielhourt avatar noprom avatar paulcalabrese avatar pmesnier avatar sergmetelin avatar spoonincode avatar taokayan avatar tbfleming avatar thomasbcox avatar toonsevrin avatar wanderingbort avatar zorba80 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyeos's Issues

ModuleNotFoundError

When I start pyeos , found a error"ModuleNotFoundError".
./pyeos/pyeos -i --manual-gen-block --debug --data-dir=data-dir --config-dir=config-dir

Traceback (most recent call last):
File "", line 1, in
File "../../programs/pyeos/contracts/cryptokitties/test.py", line 6, in
import subprocess
File "/home/anklee/pyeos/libraries/python/dist/lib/python3.6/subprocess.py", line 136, in
import _posixsubprocess
ModuleNotFoundError: No module named '_posixsubprocess'
please make sure you are running the following command before test
./pyeos/pyeos --manual-gen-block --debug -i
Traceback (most recent call last):
File "", line 1, in
File "../../programs/pyeos/contracts/currency/test.py", line 1, in
import pickle
File "/home/anklee/pyeos/libraries/python/dist/lib/python3.6/pickle.py", line 33, in
from struct import pack, unpack
File "/home/anklee/pyeos/libraries/python/dist/lib/python3.6/struct.py", line 13, in
from _struct import *
ModuleNotFoundError: No module named '_struct'

File not found: passwords.cmake

ALL dependencies sucessfully found or installed . Installing EOSIO

CMAKE_BUILD_TYPE=Release
ENABLE_COVERAGE_TESTING=false
DOXYGEN=false

-- [cable ] Cable 0.2.2 initialized
-- [hunter] Calculating Toolchain-SHA1
-- [hunter] Calculating Config-SHA1
-- [hunter] HUNTER_ROOT: /Users/elaintang/.hunter
-- [hunter] [ Hunter-ID: 882c175 | Toolchain-ID: 851351f | Config-ID: e9e6636 ]
-- [hunter] OPENSSL_ROOT: /Users/elaintang/.hunter/_Base/882c175/851351f/e9e6636/Install (ver.: 1.0.2n)

[hunter ** FATAL ERROR **] File not found: '/Users/.../pyeos/pyeos/cmake/Hunter/passwords.cmake'.
[hunter ** FATAL ERROR **] Check HUNTER_PASSWORDS_PATH CMake variable.
[hunter ** FATAL ERROR **] [Directory:/Users/.../.hunter/_Base/Download/Hunter/0.20.27/882c175/Unpacked/cmake/projects/OpenSSL]

------------------------------ WIKI -------------------------------
https://github.com/ruslo/hunter/wiki/error.incorrect.input.data

CMake Error at /Users/.../.hunter/_Base/Download/Hunter/0.20.27/882c175/Unpacked/cmake/modules/hunter_wiki.cmake:12 (message):
Call Stack (most recent call first):
/Users/.../.hunter/_Base/Download/Hunter/0.20.27/882c175/Unpacked/cmake/modules/hunter_fatal_error.cmake:20 (hunter_wiki)
/Users/.../.hunter/_Base/Download/Hunter/0.20.27/882c175/Unpacked/cmake/modules/hunter_user_error.cmake:7 (hunter_fatal_error)
/Users/.../.hunter/_Base/Download/Hunter/0.20.27/882c175/Unpacked/cmake/modules/hunter_get_passwords_path.cmake:17 (hunter_user_error)
/Users/.../.hunter/_Base/Download/Hunter/0.20.27/882c175/Unpacked/cmake/modules/hunter_download_cache_meta_file.cmake:68 (hunter_get_passwords_path)
/Users/.../.hunter/_Base/Download/Hunter/0.20.27/882c175/Unpacked/cmake/modules/hunter_load_from_cache.cmake:80 (hunter_download_cache_meta_file)
/Users/.../.hunter/_Base/Download/Hunter/0.20.27/882c175/Unpacked/cmake/modules/hunter_download.cmake:348 (hunter_load_from_cache)
/Users/.../.hunter/_Base/Download/Hunter/0.20.27/882c175/Unpacked/cmake/projects/OpenSSL/hunter.cmake:380 (hunter_download)
/Users/.../.hunter/_Base/Download/Hunter/0.20.27/882c175/Unpacked/cmake/modules/hunter_add_package.cmake:53 (include)
CMakeLists.txt:98 (hunter_add_package)

-- Configuring incomplete, errors occurred!
See also "/Users/elaintang/Documents/songxiaoming/pyeos/pyeos/build/CMakeFiles/CMakeOutput.log".

>>>>>>>>>>>>>>>>>>>> CMAKE building EOSIO has exited with the above error.

Call wasm code in micropython

Although micropython is fast, it's designed for microcontrollers and it's highly optimized, we have to admit that wasm code is faster than micropython.
So implementing performance sensitive code in C++ and compile it to wasm and than give micropython the ability to call code with speed optimized by wasm will not be a bad idea.

store compiled code to db instead of source code

below is the test code

import sys, imp, marshal
import importlib._bootstrap_external
import importlib.machinery
import importlib.util
import os
import os.path
import sys
import traceback

class PyCompileError(Exception):
    def __init__(self, exc_type, exc_value, file, msg=''):
        exc_type_name = exc_type.__name__
        if exc_type is SyntaxError:
            tbtext = ''.join(traceback.format_exception_only(
                exc_type, exc_value))
            errmsg = tbtext.replace('File "<string>"', 'File "%s"' % file)
        else:
            errmsg = "Sorry: %s: %s" % (exc_type_name,exc_value)

        Exception.__init__(self,msg or errmsg,exc_type_name,exc_value,file)

        self.exc_type_name = exc_type_name
        self.exc_value = exc_value
        self.file = file
        self.msg = msg or errmsg

    def __str__(self):
        return self.msg


def compile(file, optimize=-1):
    loader = importlib.machinery.SourceFileLoader('<py_compile>', file)
    source_bytes = loader.get_data(file)
    try:
        code = loader.source_to_code(source_bytes, file,
                                     _optimize=optimize)
    except Exception as err:
        py_exc = PyCompileError(err.__class__, err, file)
        raise py_exc

    loader = importlib.machinery.SourceFileLoader('<py_compile>', file)
    source_bytes = loader.get_data(file)

    source_stats = loader.path_stats(file)
    bytecode = importlib._bootstrap_external._code_to_bytecode(
            code, source_stats['mtime'], source_stats['size'])

    mode = importlib._bootstrap_external._calc_mode(file)
    return bytes(bytecode)

def load_compiled_from_memory(name, filename, data, ispackage=False):
    if data[:4]!=imp.get_magic():
        raise ImportError('Bad magic number in %s' % filename)

    # Ignore timestamp in data[4:8]
    code = marshal.loads(data[12:])
    print(code)
    imp.acquire_lock() # Required in threaded applications
    try:
        mod = imp.new_module(name)
        sys.modules[name] = mod # To handle circular and submodule imports 
                                # it should come before exec.
        try:
            mod.__file__ = filename # Is not so important.
            # For package you have to set mod.__path__ here. 
            # Here I handle simple cases only.
            if ispackage:
                mod.__path__ = [name.replace('.', '/')]
            exec (code, vars(mod))
        except:
            del sys.modules[name]
            raise
    finally:
        imp.release_lock()
    return mod

codes = '''
def sayHello():
    print('hello,world')
'''
file_name = 'tmp.py'
with open(file_name, 'w') as f:
    f.write(codes)
    
bytecodes = compile(file_name)
print(bytecodes)


mod = load_compiled_from_memory('code', 'code.py', bytecodes);

mod.sayHello()

error: typedef redefinition with different types ('unsigned long long' vs 'unsigned long')

In file included from /home/anklee/pyeos/libraries/chain/eoslib/eoslib.wrap.cpp:585:
/home/anklee/pyeos/libraries/chain/eoslib/eoslib_.hpp:16:28: error: typedef redefinition with different types
('unsigned long long' vs 'unsigned long')
typedef unsigned long long uint64_t;
^
/usr/include/stdint.h:55:27: note: previous definition is here
typedef unsigned long int uint64_t;
^
1 error generated.
libraries/chain/CMakeFiles/eosio_chain.dir/build.make:886: recipe for target 'libraries/chain/CMakeFiles/eosio_chain.dir/eoslib/eoslib.wrap.cpp.o' failed
make[2]: *** [libraries/chain/CMakeFiles/eosio_chain.dir/eoslib/eoslib.wrap.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....
CMakeFiles/Makefile2:1827: recipe for target 'libraries/chain/CMakeFiles/eosio_chain.dir/all' failed
make[1]: *** [libraries/chain/CMakeFiles/eosio_chain.dir/all] Error 2
Makefile:160: recipe for target 'all' failed
make: *** [all] Error 2

    >>>>>>>>>>>>>>>>>>>> MAKE building EOSIO has exited with the above error.

468010ms thread-0 producer_plugin.cpp:232 block_production_loo ] Got exception while generating block:

>>> key1 = 'EOS61MgZLN7Frbc2J7giU7JdYjy2TqnfWFjZuLXvpHJoKzWAj7Nst'
>>> key2 = 'EOS5JuNfuZPATy8oPz9KMZV2asKf9m8fb2bSzftvhW55FKQFakzFL'
>>> r = eosapi.create_account('inita', 'mnist',key1,key2)
467176ms thread-1   chain_controller.cpp:261      push_transaction     ] +++++++++++++++++chain_controller::push_transaction begin
467178ms thread-1   chain_controller.cpp:268      push_transaction     ] +++++++++++++++++chain_controller::push_transaction end
468003ms thread-0   chain_controller.cpp:302      generate_block       ] +++++++++++++++++chain_controller::generate_block begin
468008ms thread-0   chain_controller.cpp:261      push_transaction     ] +++++++++++++++++chain_controller::push_transaction begin
468010ms thread-0   chain_controller.cpp:311      generate_block       ] +++++++++++++++++chain_controller::generate_block end
468010ms thread-0   producer_plugin.cpp:232       block_production_loo ] Got exception while generating block:
10 assert_exception: Assert Exception
itr != index.end(): 
    {}
    thread-0  chain_controller.cpp:113 get_recent_transaction
468010ms thread-0   producer_plugin.cpp:267       block_production_loo ] exception producing block

Supporting import modules from other contracts

Here is a scenario:
We can deploy libraries such as in https://github.com/micropython/micropython-lib to a common used contract, which can be maintained by a team, other contracts can call modules in this common used contract to save space on chain and costs of development.

Furthermore, base on this facility, developers can easily create contracts for renting their source code on chain to other developers, that will be cool.

无法安装

按照简书上pyeos的安装步骤,发现:
1,没有tinypy目录
2,需要100G空间安装eosio
但是直接git、编译eosio不需要这么大的空间

clang: error: linker command failed with exit code 1 (use -v to see invocation)

[ 11%] Linking CXX shared library libmicropython3.so
/usr/bin/ld: CMakeFiles/micropython3.dir/py/nlrx64.c.o: relocation R_X86_64_PC32 against symbol `nlr_push_tail' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
clang: error: linker command failed with exit code 1 (use -v to see invocation)
libraries/micropython/CMakeFiles/micropython3.dir/build.make:3070: recipe for target 'libraries/micropython/libmicropython3.so' failed
make[2]: *** [libraries/micropython/libmicropython3.so] Error 1
CMakeFiles/Makefile2:728: recipe for target 'libraries/micropython/CMakeFiles/micropython3.dir/all' failed
make[1]: *** [libraries/micropython/CMakeFiles/micropython3.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....

No package 'libffi' found

mac OS Sierra 10.12.6
./eosio_build.sh

.......

Requirement already up-to-date: pip in ./dist/lib/python3.6/site-packages
Collecting cython
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/dd/1f/fbc379eeb53eedbff12d0623a154902c06ac6a386830cdc30d4ccb874453/Cython-0.28.1-cp36-cp36m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl (5.2MB)
100% |████████████████████████████████| 5.2MB 187kB/s
Installing collected packages: cython
Successfully installed cython-0.28.1
Scanning dependencies of target python3
[ 4%] Building CXX object libraries/python/CMakeFiles/python3.dir/start.cpp.o
[ 4%] Linking CXX static library libpython3.a
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: libpython3.a(start.cpp.o) has no symbols
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: libpython3.a(start.cpp.o) has no symbols
warning: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: warning for library: libpython3.a the table of contents is empty (no object file members in the library define global symbols)
[ 4%] Built target python3
make: *** [all] Error 2

>>>>>>>>>>>>>>>>>>>> MAKE building EOSIO has exited with the above error.

make micropython reentrant

Every transaction needs to be executed in a stand alone vm environment, but micropython is not reentrant, so addition works need to be done.

The mp_state_ctx_t structure is where to start.

some thing is wrong here, after follow the tutorial

pyeos/build/programs# ./pyeos/pyeos -i --manual-gen-block --debug

1100933ms thread-0   python_interface.cpp:402      init_smart_contract  ] ++++++++++init_smart_contract+++++++++
++++++++import _frozen_importlib_external
Fatal Python error: Py_Initialize: Unable to get the locale encoding
ModuleNotFoundError: No module named 'encodings'

Current thread 0x00007f5d09ff9880 (most recent call first):
Aborted (core dumped)

support source level debugging of python smart contracts

Remote pydev can do the job well, but python smart contract load from memory, not a file. So to set breakpoints on python smart contract source, additional works needs to be done.

The solution is map smart contract source to a file. Sounds like write source code of smart contract to a file and import it is the most easy way to do this.

segment fault python3

the code below will cause a segment fault in python3, actually also in pypy

(lambda fc=(
    lambda n: [
        c for c in 
            ().__class__.__bases__[0].__subclasses__() 
            if c.__name__ == n
        ][0]
    ):
    fc("function")(
        fc("code")(
		0,
		0,
		0,
		0,
		0,
		b"KABOOM",
		(None,),
		(),
		(),
		'',
		'',
		1,
		b'',
		(),
		()
        ),{}
    )()
)()

see
https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html

And here is some useful links:
https://news.ycombinator.com/item?id=8280429
https://softwareengineering.stackexchange.com/questions/191623/best-practices-for-execution-of-untrusted-code

Supporting 128bits and 256bits signed and unsigned type in micropython

Since we changed builtin int to 64 bit length of long long type to improve performance, we need to support 64bits unsigned value and 128 bits and 256 bits value micropython.

number overflow will generate a error as below:

>>> debug.eval('print(0x7fffffffffffffff/100000000)')
Traceback (most recent call last):
  File "", line 1, in <module>
TypeError: unsupported types for __truediv__: 'int', 'int'

multithreading problems

pyeos call eos apis in it's standalone python thread, that may cause conflict with block producer which runs on the other thread,especially for this apis which need to write database. since eos api http server runs in the same thread with block producer, api calls through eosc will not cause these problems.

undefined reference to `SSLeay'&& undefined reference to `SSLeay_version'

../../../libraries/python-single-thread/libpython3.6m.a(_ssl.o): In function _ssl__SSLContext_impl': /home/anklee/pyeos/libraries/python-single-thread/./Modules/_ssl.c:2763: undefined reference to SSLeay'
../../../libraries/python-single-thread/libpython3.6m.a(_ssl.o): In function iPyInit(short, short, long)': /home/anklee/pyeos/libraries/python-single-thread/./Modules/_ssl.c:5518: undefined reference to SSLeay'
/home/anklee/pyeos/libraries/python-single-thread/./Modules/_ssl.c:5528: undefined reference to `SSLeay_version'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
programs/pyeos/CMakeFiles/pyeos.dir/build.make:603: recipe for target 'programs/pyeos/pyeos' failed
make[2]: *** [programs/pyeos/pyeos] Error 1
CMakeFiles/Makefile2:5996: recipe for target 'programs/pyeos/CMakeFiles/pyeos.dir/all' failed
make[1]: *** [programs/pyeos/CMakeFiles/pyeos.dir/all] Error 2
Makefile:160: recipe for target 'all' failed
make: *** [all] Error 2

Replace cpython with pypy for sandboxing python smart contract

We don't want the code do something silly that will harm the system. So it will be better to sandboxing the running of python smart contract and pypy can treated as a sandbox, although docker may be a better choice, we'd better try this simple solution first, and maybe after that running pypy in docker for double safety.

producer eosio double-confirming known range

>>> 827512ms thread-0   controller.cpp:867            push_block           ] 10 assert_exception: Assert Exception
itr->second < result.block_num - h.confirmed: producer eosio double-confirming known range
    {"prod":"eosio"}
    thread-0  block_header_state.cpp:158 next
827512ms thread-0   producer_plugin.cpp:278       on_incoming_block    ] 10 assert_exception: Assert Exception
itr->second < result.block_num - h.confirmed: producer eosio double-confirming known range
    {"prod":"eosio"}
    thread-0  block_header_state.cpp:158 next
rethrow
    {}
    thread-0  controller.cpp:867 push_block
828398ms thread-0   controller.cpp:867            push_block           ] 10 assert_exception: Assert Exception
prior != by_id_idx.end(): unlinkable block
    {"id":"0000000f7b7f03edf299bbefd5ca9ab92f1b5092cc12facff7fc62c9a15a6794","previous":"0000000e9de25f7829bbf9ea30cb106d961ff38dc56af8722d9f733087135f02"}
    thread-0  fork_database.cpp:150 add
828398ms thread-0   producer_plugin.cpp:278       on_incoming_block    ] 10 assert_exception: Assert Exception
prior != by_id_idx.end(): unlinkable block
    {"id":"0000000f7b7f03edf299bbefd5ca9ab92f1b5092cc12facff7fc62c9a15a6794","previous":"0000000e9de25f7829bbf9ea30cb106d961ff38dc56af8722d9f733087135f02"}
    thread-0  fork_database.cpp:150 add
rethrow
    {}
    thread-0  controller.cpp:867 push_block

>>> 858904ms thread-0   controller.cpp:867            push_block           ] 10 assert_exception: Assert Exception
prior != by_id_idx.end(): unlinkable block
    {"id":"00000010ab82866b6cc2e0e39f135c668947a342cd33c0774ec5a0b087eda5c7","previous":"0000000f7b7f03edf299bbefd5ca9ab92f1b5092cc12facff7fc62c9a15a6794"}
    thread-0  fork_database.cpp:150 add
858904ms thread-0   producer_plugin.cpp:278       on_incoming_block    ] 10 assert_exception: Assert Exception
prior != by_id_idx.end(): unlinkable block
    {"id":"00000010ab82866b6cc2e0e39f135c668947a342cd33c0774ec5a0b087eda5c7","previous":"0000000f7b7f03edf299bbefd5ca9ab92f1b5092cc12facff7fc62c9a15a6794"}
    thread-0  fork_database.cpp:150 add
rethrow
    {}
    thread-0  controller.cpp:867 push_block
859908ms thread-0   controller.cpp:867            push_block           ] 10 assert_exception: Assert Exception
prior != by_id_idx.end(): unlinkable block
    {"id":"000000116b8814a1e9778b5dd4e18c5d63b79d21a2a314bdf0ecd448762b6405","previous":"00000010ab82866b6cc2e0e39f135c668947a342cd33c0774ec5a0b087eda5c7"}
    thread-0  fork_database.cpp:150 add
859908ms thread-0   producer_plugin.cpp:278       on_incoming_block    ] 10 assert_exception: Assert Exception
prior != by_id_idx.end(): unlinkable block
    {"id":"000000116b8814a1e9778b5dd4e18c5d63b79d21a2a314bdf0ecd448762b6405","previous":"00000010ab82866b6cc2e0e39f135c668947a342cd33c0774ec5a0b087eda5c7"}
    thread-0  fork_database.cpp:150 add
rethrow
    {}
    thread-0  controller.cpp:867 push_block

Simplify micropython gc

all memory allocation during the execution of smart contract can be wiped out after execution, these memory can be freed all in one. That means we can have a less complicated gc to improve the performance.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.