Code Monkey home page Code Monkey logo

serpent's Introduction

Introduction

Serpent is an assembly language that compiles to EVM code that is extended with various high-level features. It can be useful for writing code that requires low-level opcode manipulation as well as access to high-level primitives like the ABI.

Being a low-level language, Serpent is NOT RECOMMENDED for building applications unless you really really know what you're doing. The creator recommends Solidity as a default choice, LLL if you want close-to-the-metal optimizations, or Viper if you like its features though it is still experimental.

Installation:

make && sudo make install

Testing

Testing is done using pytest and tox.

$ pip install tox -r requirements-dev.txt

To run the test suite in your current python version:

$ py.test

To run the full test suite across all supported python versions:

$ tox

serpent's People

Contributors

caktux avatar changwu-tw avatar ebuchman avatar ethers avatar gavofyork avatar giact avatar jorisbontje avatar mode80 avatar nicksavers avatar o-jasper avatar pipermerriam avatar reorder avatar tinybike avatar utzig avatar vbuterin 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

serpent's Issues

behavior when refactoring inset to extern

sand2.py has:

data heaviestBlock

def bar(n):
    log(111)
    log(self.heaviestBlock)
    self.heaviestBlock = n*10

    log(222)
    log(self.heaviestBlock)

sand3.py has:

extern two: [bar:i:_]
TWO = create('sand2.py')

def foo(n):
    TWO.bar(n)

output is:

>>> c=s.abi_contract('sand3.py')
>>> c.foo(3)
('LOG', '511025535e12a356197fa0c1c2a53a6617186f93', [111], [])
('LOG', '511025535e12a356197fa0c1c2a53a6617186f93', [0], [])
('LOG', '511025535e12a356197fa0c1c2a53a6617186f93', [222], [])
('LOG', '511025535e12a356197fa0c1c2a53a6617186f93', [30L], [])
>>> c.foo(4)
('LOG', '83891c69d6a98ba3a83cc6b9dab025b4c5ad2325', [111], [])
('LOG', '83891c69d6a98ba3a83cc6b9dab025b4c5ad2325', [0], [])
('LOG', '83891c69d6a98ba3a83cc6b9dab025b4c5ad2325', [222], [])
('LOG', '83891c69d6a98ba3a83cc6b9dab025b4c5ad2325', [40L], [])

If inset was used and extern were not used, c.foo(4) would log 30 after 111:

>>> c.foo(4)
('LOG', '83891c69d6a98ba3a83cc6b9dab025b4c5ad2325', [111], [])
('LOG', '83891c69d6a98ba3a83cc6b9dab025b4c5ad2325', [30], [])

I am opening this suggestion because it would be nice if replacing code that used inset, would still behave similarly when using extern.

Compiler doesnt spot nonexistant variables.

This means a simple typo can have consequences that are only spotted later when the value matters, instead of immediately. (return(x) to see it)

Probably it allocates memory for the variable meaning the value starts at zero.

Private functions? The danger of exposing functions?!

Is there a way to make private functions? Might if msg.sender == self: suffice?

Infact accidentally not having some functions not private can be downright disasterous. For instance, i am upgrading my assurance contracts to the newer serpent/Ethereum, and i have a refund() option for the creator, and a finish() function that decides whether to refunds.

God forbid that someone decides to refactor the internals, _refund(), with no checking on whois asking. I think this warrants a warning.. Infact, perhaps functions need to be defaultly private?!

unable to modify string

def f2(string:s):
    setch(string, 0, "a")
    setch(string, 1, "b")

def t2():
    string = text("cd")
    self.f2(string)
    return([getch(string,0), getch(string,1)]:a)  # should return [97,98]

when calling t2()
actual: [99,100]
expected: [97,98]

Does ``return`` only return a single 256 bit word?

Note: The example uses serpent on the develop branch with revision c9563cff.

The following example tries to return a long text string. An examination of the LLL output makes it seem as if only 32 bytes are returned in the expression (return (ref '_temp_131) 32). Am I misreading this LLL expression?

$ cat > long_string_return.se
return text("This is 53 characters, which is longer than 256 bits.")

$ serpent compile_to_lll !$
serpent compile_to_lll long_string_return.se
(return 0
  (lll
    (seq
      (set '_temp_131
        (with '_temp17_str (alloc 85)
          (seq
            (mstore (get '_temp17_str) 53)
            (mstore (add (get '_temp17_str) 32)
              38178759162904981153227459547417441039765882805204013944776380134389117973280
            )
            (mstore (add (get '_temp17_str) 64)
              49046669650839314774563824355363137219616139645592700948219339121638676365312
            )
            (add (get '_temp17_str) 32)
          )
        )
      )
      (return (ref '_temp_131) 32)
    )
    0
  )
)

Unexpected array behaviour

this code:

a = array(1)
a[0] = 1
return(a, 1)

returns 0 (unexpected)

this code:

a = array(1)
something = 2
a[0] = 1
return(a, 1)

for some reason returns 1 (expected)

Name: ethereum-serpent
Version: 1.6.3

modifying array in another function

def f2(arr:a):
    arr[0] = 1
    arr[1] = 2

def t2():
    a = array(2)
    a[0] = 3
    a[1] = 4
    self.f2(a)
    return(a:a)

when calling t2()
actual: [3,4]
expected: [1,2]

return([1,2,3], items=3) # No array returned latest devel commit

Hi, thanks for your great work Vitalik. I am using serpent for some exchange contracts. I encountered the problem that functions don't return arrays but integers. I am working on the latest develop commit.

def return_array():
......return([1,2,3], items=3)

def main():
.....log(self.return_array()) # logs ('LOG', 'c305c901078781c232a2a521c2af7980f8385ee9', [1L], [])

examples/quicksort_pairs.py gives wrong results

Sorting does not work as expected. Afik, this issue is not related to #8.

from pyethereum import tester
def test_quicksort():
    s = tester.state()
    c = s.contract('quicksort_pairs.se')
    data = [30, 1, 90, 2, 70, 3, 50, 4]
    expected = [30, 1, 50, 4, 70, 3, 90, 2]
    r = s.send(tester.k0, c, 0, data=data)
    assert expected == r, (expected, r)
test_quicksort()
(default) ~/dev/ethereum/fuelbattles/serpent (git)-[master] % python test_quicksort_pairs.py 
Traceback (most recent call last):
  File "test_quicksort_pairs.py", line 11, in <module>
    test_quicksort()
  File "test_quicksort_pairs.py", line 9, in test_quicksort
    assert expected == r, (expected, r)
AssertionError: ([30, 1, 50, 4, 70, 3, 90, 2], [30, 1, 0, 0, 70, 3, 90, 2])

space saver

when serpent compiles, it gives things like: PUSH2 0 125 JUMP
more efficient equivalent EVM code: PUSH1 125 JUMP

idk where in the code to fix it from.
The trick to tell how many bytes you need to store number N: log(N)/log(256)

storing an array to storage

what's the recommended way to do this?

data gArr[]

def f2():
    arr = array(2)
    arr[0] = 1
    arr[1] = 2
    return(arr:a)

def t2():
    self.gArr = self.f2(outsz=2)
    # return(self.gArr:a)

As is, it's a compile error on the line with self.gArr: Too few array index lookups

setch not working?

def f1(string:s):
    setch(string, 0, "a")
    setch(string, 1, "b")
    return(string)

def t1():
    string = text("cd")
    res = self.f1(string)
    return([getch(res,0), getch(res,1)]:a)  # should return [97,98]

when call t1()
actual: [99, 100]
expected: [97, 98]

help installing serpent please

hi, can anyone link me to a step by step guide for installing/testing Serpent? I have a VM Ubuntu box set up already. I'm really new to all this, but really excited to play around with the technology! Please help!

0xfe invalid opcode should be removed?

I have a contract that when compiled has some parts JUMPI 0xfe. Alethzero does not allow contract creation with invalid opcode 254:

<INVALID_INSTRUCTION: 254 >
 Dynamic exception type: std::out_of_range
std::exception::what: map::at

For a repro, paste this in AZ "New Transaction" 6006600957fe5b60035b6004 and click Debug. Look at AZ log for error above.

inset() is changing behavior of function that writes to storage

When inset() is not used, calling testingonlySetGenesis() in code below writes data to storage and things are good.

However, when top of file is placed in another file and inset() is used (as mentioned in code comment), testingonlySetGenesis does not store data: it is also unclear what happens because this tx cannot be debugged by Alethzero (AZ shows blank http://imgur.com/DMArfoC )

data numAncestorDepths
self.numAncestorDepths = 9  # if change, look at defn of ancestor_depths and block in btcrelay.py
data ancestor_depths[9]

self.ancestor_depths[0] = 1
self.ancestor_depths[1] = 4
self.ancestor_depths[2] = 16
self.ancestor_depths[3] = 64
self.ancestor_depths[4] = 256
self.ancestor_depths[5] = 1024
self.ancestor_depths[6] = 4096
self.ancestor_depths[7] = 16384
self.ancestor_depths[8] = 65536
########### BUG IS IF ABOVE IS PUT IN ANOTHER FILE and replaced with inset() here ######

# block with the highest score (the end of the blockchain)
data heaviestBlock

# highest score among all blocks (so far)
data highScore

# note: _ancestor[9]
data block[2^256](_height, _score, _ancestor[9], _blockHeader[])

extern btc_eth: [processTransfer:s:i]


#TODO for testing only
def testingonlySetGenesis(blockHash):
    self.heaviestBlock = blockHash
    self.block[blockHash]._height = 1
    ancLen = self.numAncestorDepths
    i = 0
    while i < ancLen:
        self.block[blockHash]._ancestor[i] = blockHash
        i += 1

getting length of array

since the calling syntax is foo(array:size) maybe inside foo(), the length of array can be obtained by a syntax like len(array)

Compiled Serpent subcurrency example turns into STOP STOP STOP in AlethZero

Taking a Serpent compiled contract, submitting it to AlethZero by copy/pasting the hexstring into the "(Create Contract)" Data field returns into a persisted contract with a lot of STOP STOP STOP instructions up front... which won't execute.

Serpent sourcecode:

init:
    contract.storage[msg.sender] = 1000000
code:
    if msg.datasize == 1:
        addr = msg.data[0]
        return(contract.storage[addr])
    else:
        from = msg.sender
        fromvalue = contract.storage[from]
        to = msg.data[0]
        value = msg.data[1]
        if fromvalue >= value:
            contract.storage[from] = fromvalue - value
            contract.storage[to] = contract.storage[to] + value
            return(1)
        else:
            return(0)

Compiling with serpent compile (serpent version 51cd8f4)

$ serpent compile examples/subcurrency.se
620f424033576100775160006100143961008b586001602036040e0f610022596000356020546020535660405460206040f261007758336060546060535660805460003560a05460203560c05460c0536080530c0f0f61006b5960c053608053036060535760c05360a053560160a05357600160e054602060e0f2610077586000610100546020610100f26000f2

Or the pretty version:

$ serpent pretty_compile examples/subcurrency.se
[PUSH3, 15, 66, 64, CALLER, SSTORE, PUSH2, 0, 119, DUP, PUSH1, 0, PUSH2, 0, 20, CODECOPY, PUSH2, 0, 139, JUMP, PUSH1, 1, PUSH1, 32, CALLDATASIZE, DIV, EQ, NOT, PUSH2, 0, 34, JUMPI, PUSH1, 0, CALLDATALOAD, PUSH1, 32, MSTORE, PUSH1, 32, MLOAD, SLOAD, PUSH1, 64, MSTORE, PUSH1, 32, PUSH1, 64, RETURN, PUSH2, 0, 119, JUMP, CALLER, PUSH1, 96, MSTORE, PUSH1, 96, MLOAD, SLOAD, PUSH1, 128, MSTORE, PUSH1, 0, CALLDATALOAD, PUSH1, 160, MSTORE, PUSH1, 32, CALLDATALOAD, PUSH1, 192, MSTORE, PUSH1, 192, MLOAD, PUSH1, 128, MLOAD, SLT, NOT, NOT, PUSH2, 0, 107, JUMPI, PUSH1, 192, MLOAD, PUSH1, 128, MLOAD, SUB, PUSH1, 96, MLOAD, SSTORE, PUSH1, 192, MLOAD, PUSH1, 160, MLOAD, SLOAD, ADD, PUSH1, 160, MLOAD, SSTORE, PUSH1, 1, PUSH1, 224, MSTORE, PUSH1, 32, PUSH1, 224, RETURN, PUSH2, 0, 119, JUMP, PUSH1, 0, PUSH2, 1, 0, MSTORE, PUSH1, 32, PUSH2, 1, 0, RETURN, PUSH1, 0, RETURN]

alethzero

alethzero2

The contract initialization seems to work, but then the contract is rendered useless by the STOPs, trailing instructions of the contract are also trimmed.

(This issue was previously reported on the now deleted ethereum/langs repository)

byte() is not working on loaded or spliced strings

Problem is in the code and comment bellow:

data buf[]

def foo():
    mystr=text("81cd02ab7e569e8bcd9317e2fe99f2de44d49ab2b8851ba4a308000000000000e320b6c2fffc8d750423db8b1eb942ae710e951ed797f7affc8892b0f1fc122b81cd02ab7e569e8bcd9317e2fe99f2de44d49ab2b8851ba4a308000000000000e320b6c2fffc8d750423db8b1eb942ae710e951ed797f7affc8892b0f1fc122b")
    save(self.buf[0], mystr, chars=len(mystr))

    self.g()

def g():
    jstr = load(self.buf[0], chars=132)
    log(datastr=jstr)

    j = slice(jstr, chars=128, chars=132)
    log(datastr=j)

    b = byte(0, jstr)  # gets 0 when jstr or j is used.  byte only works when self.buf[0] is used instead of jstr
    log(b)

poc7 serpent not recognizing 'if' statement

When trying to compile the stock short_namecoin.se example with the POC7 branch of serpent:

$ serpent compile short_namecoin.se
Error (file "short_namecoin.se", line 2, char 720899): Not a function or opcode: if

Char numbering seems off as well.

Using log(data=a) with an array prints each byte, not each item

If my array is [1, 2, 3], shouldn't log print [1, 2, 3], and not [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3]?

how to save string to global

data buf

def foo():
    mystr = text("01ab")
    save(self.buf, mystr:str)

combinations of using buf[] and save(self.buf, mystr, chars=4) also do not work

Returning array with first element as 0 fails

The following serpent test code fails when the first returned array element is a 0:

def get_stops(rnd):
    stops = array(REEL_COUNT)
    i = 0
    while i < REEL_COUNT:
        stops[i] = rnd % REEL_POSITIONS
        rnd = rnd / REEL_POSITIONS
        i += 1
    return(stops:a)

Full serpent + test code: https://gist.github.com/jorisbontje/99a30029a3d15f065e13/757dded2ae95835010b6c09f1878a951a324278e

_______________________________________________________ TestStops.test_get_stops ________________________________________________________

self = <test_stops.TestStops object at 0x110ce0490>

    def test_get_stops(self):
        assert self._get_stops(23888)[:3] == [16, 10, 23]
        assert self._get_stops(1606)[:3] == [6, 18, 1]
        assert self._get_stops(23888)[:3] == [16, 10, 23]
>       assert self._get_stops(30464)[:3] == [0, 24, 29]
E       assert [] == [0, 24, 29]
E         Right contains more items, first extra item: 0
E         Full diff:
E         - []
E         + [0, 24, 29]

test/test_stops.py:35: AssertionError

This is with serpent 1.7.8

Expected would be that the array [0, 24, 29] would be returned.

global variable scoping/modifying

see inline comment in code below:

data pos
self.pos=0


def readVarintNum():
    log(self.pos)  # shouldn't self.pos be 4 here ?  or how can I update self.pos from readUInt32LE() ?

def readUInt32LE():
    self.pos += 4

def run():
    self.pos = 0
    self.readUInt32LE()
    log(self.pos)
    ins = self.readVarintNum()

Potential optimizations

Compiler macros are general functions that apply on an expression first, and return nothing if they do not apply, or the resulting expression.

A lot can already be achieved with the replacement rules already, of course.

Find-the-function.

Perhaps instead of having a lot of (when (eq (ge '__funid) ...) you can see if (lt (ge '__funid ...) < ) and go through branches of the Tree. Is log2(N) instead of N, no disadvantage that i see.

I think it is probably best if LLL has a (case ...) and then you make case figure it out.

unless (iszero..)

What's wrong with when?

Orring:

As observed.(whitespace altered)

(with '_temp_10201 (slt (get 'i) 1) 
    (if (get '_temp_10201) 
        (get '_temp_10201) 
        (sgt (get 'i) (sload 5))))

This might be fine for a value-or, returning the first non-false value. But if the value is just used as a boolean, should use the bitwise or. For simpler cases compiler macros can recognize it.

Memory values

Mark variables that the compiler makes and you know wont change.(For instance in the above or case.)

When can variables be substituted with their expressions?

  1. Variable is never set before that.
  2. Expressions are constant. (no call, mload, sload(AFAIK) although you might be able to check whether the latter two matter in this case)
  3. Expressions do not make changes. (no call, sstore, mstore(AFAIK))

If you know when substituting is allowed, choosing whether to do it is figuring out what is more efficient.

I think i.e. (calldataload ..constant..), (number), (timestamp), constant all qualify if the variable is not changed. This might already help a lot!

More complicatedly, could estimate the gas cost. Either for contract creation or when running the code. (can 'settings' wrt optimization at branch in the AST-tree. I.e (optimize-for-run and (optimize-for-codelen?) Or (optimization-ratio r, i.e. saving r running gas is worth 1 creation-gas.

Arrays

Not sure.. If there is just one array with no particular length you can just use (+ (* itemsz i) last_index) instead of going the sha3 route?

Or do low indexes cause pain? ("continuous area?") Another argument against is that it makes where-things-are-stored less predictable. (dont think that is very important tho)

Powers of two

That is 2224 ... Probably better to denote that way?

(with '__funid 
    (div (calldataload 0)
        26959946667150639794667015087019630673637144422540572481103610249216)
    ....

Right EXP is not expensive. Could be cheaper though, if there was a EXP2

global string value is lost

the log in foo() shows correct, but the log in g() is empty... ?

data buf

def foo():
    mystr = text("01ab")
    self.buf = mystr
    log(datastr=self.buf)
    self.g()

def g():
    log(datastr=self.buf)  # this logs empty

poc7 empty def on crowdfund example

Using poc7 build of serpent on the stock crowdfund example:

$ serpent compile crowdfund.se
Error (file "crowdfund.se", line 1, char 107): Empty def

crowdfund.se example gives: Multiple expressions or unclosed bracket

$ serpent compile crowdfund.se
Error (file "crowdfund.se", line 1, char 107): Multiple expressions or unclosed bracket
Traceback (most recent call last):
  File "/usr/local/bin/serpent", line 9, in <module>
    load_entry_point('ethereum-serpent==1.7.3', 'console_scripts', 'serpent')()
  File "/usr/local/bin/serpent.py", line 192, in main
    o = globals()[cmd](*args)
  File "/usr/local/bin/serpent.py", line 74, in <lambda>
    compile = lambda x: pyext.compile(x)
Exception: Error (file "crowdfund.se", line 1, char 107): Multiple expressions or unclosed bracket

broken compilation

With ethereum-serpent==1.78:

> serpent compile 'return(msg.data[0] * 2)'
Error (file "main", line 1, char 10): Invalid object member (ie. a foo.bar not mapped to anything)
Traceback (most recent call last):
  File "/usr/bin/serpent", line 9, in <module>
    load_entry_point('ethereum-serpent==1.7.8', 'console_scripts', 'serpent')()
  File "/usr/bin/serpent.py", line 197, in main
    o = globals()[cmd](*args)
  File "/usr/bin/serpent.py", line 74, in <lambda>
    compile = lambda x: pyext.compile(x)
Exception: Error (file "main", line 1, char 10): Invalid object member (ie. a foo.bar not mapped to anything)

inset at top of file doesn't work

inset('bar.py')

# this is what's in bar.py
# def g(n):
#     return(n+10)
#
# def f(n):
#     return(n*2)


def foo():
    res = self.g(12)

    return(res)

On my machine, the return value is always [10], regardless of which function is called.

Moving inset() to the bottom of the file is a workaround.

unable to return a string from a function

def getString():
    str = text("abc")
    return(str)  # cannot use str:s here since Exception Transaction failed

def run():
    res = self.getString()
    return(getch(res, 0))

when calling run()
actual: 0
expected: 97

value of variable is clobbered

call test2() and the expected output is to log 2 twice, but numAncestorDepths gets clobbered.

data block[2^256](_blockHeader(_prevBlock))

data numAncestorDepths
def initAncestorDepths():
    self.numAncestorDepths = 2

def testStoreB(number, blockHash, hashPrevBlock):
    self.block[blockHash]._blockHeader._prevBlock = hashPrevBlock

    log(self.numAncestorDepths)


def test2():
    self.initAncestorDepths()
    self.testStoreB(45, 45, 44)
    self.testStoreB(46, 46, 45)  # this will log 45 (expected is to still log 2)

no `PyExt.compile`?

Get this with all of PyExt(master, 51bd6f2 and 1df7914) and 0.7 here. Got this trying to run the test of cryptocoinwatch. The following reproduces for me.(which particular file doesnt matter)

from serpent import compile
file = '/home/jasper/oproj/ethereum/contracts/cryptocoinwatch/cryptocoinwatch.se'
print(compile(open(file).read()).encode('hex'))

Searching the code of PyExt, i dont see compile in there, and checked that pip install pyext gets the same 0.7 files.

Compiled serpent code with insets doesn't work in js abi

When I use the JS API to connect to alethzero I can publish a compiled hex serpent contract without insets and a simple function call like double(2) will return 4. If I have an inset, even if the inset doesn't do anything, it returns 0

Loops of Length 311 are Too Big for init Functions

I am having problems with using while loops in def init(): functions in Contracts.

Specifically, I have installed the following versions of serpent and pyethereum:

pip install -q --upgrade \
  git+git://github.com/ethereum/serpent.git@86649c54c209a662c943d664819fe01b8ebc3e2b \
  git+git://github.com/ethereum/pyethereum.git@23c7d1e551c3c94d11fdea66cfdb7d29b17b8a50

Here's my contract:

# array_init.se
data arr[312]

def init():
    i = 0
    while i < 311:
        self.arr[i] = 1
        i = i + 1

def foo():
    return 1

312 happens to be the length of the buffer used by Mersenne Twister.

If I replace 311 with 310, there are no problems.

Here's how I am testing this code:

from pyethereum import tester as t
s = t.state()
c = s.contract('array_init.se')
for _ in range(5):
    gas_start = s.block.gas_used
    print s.send(t.k0, c, 0, funid=0, abi=[])[0]

Should print 1 five times. Instead here's my exception and stacktrace:

---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
<ipython-input-37-fa2ff0671689> in <module>()
      1 from pyethereum import tester as t
      2 s = t.state()
----> 3 c = s.contract('array_init.se')
      4 for _ in range(5):
      5     gas_start = s.block.gas_used

/usr/local/lib/python2.7/site-packages/pyethereum/tester.pyc in contract(self, code, sender, endowment)
     60     def contract(self, code, sender=k0, endowment=0):
     61         evm = serpent.compile(code)
---> 62         o = self.evm(evm, sender, endowment)
     63         assert len(self.block.get_code(o)), "Contract code empty"
     64         return o

/usr/local/lib/python2.7/site-packages/pyethereum/tester.pyc in evm(self, evm, sender, endowment)
     70         (s, a) = pb.apply_transaction(self.block, tx)
     71         if not s:
---> 72             raise Exception("Contract creation failed")
     73         return a
     74 

Exception: Contract creation failed

Method signatures are incompatible with ethereum.js

By that I mean the 4 bytes "prefix", which should not be from sha3(method_name + input_signatures) but simply from sha3(method_name). The "as" keyword should also be brought back instead of using input signatures to differentiate methods for externs.

Inconsistency in (string) padding between serpent/pyethereum and cpp-ethereum/AlethZero

With Serpent 1.5.4:

>>> serpent.encode_datalist(["set", 1, 2])
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00set
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02'

With AlethZero (POC5 and develop):
screen shot 2014-08-01 at 15 18 43

With Serpent the string "set" is left padded with NULLs. On AlethZero strings are right padded.
I would expect the padding to be the same for compatibility reasons.

collatz example is broken

  • it refers to msg.data, but msg.data isn't supported (or is it?)
  • the first equality if (x % 2) == 0 does not parse, it needs to be if ((x % 2) == 0).
  • it's the first example in the directory. heh.

Unable to compile develop branch

I'm trying to compile develop. When I run make I get the following error (running Xubuntu 14.04, previous versions have compiled successfully):

jack@heavy:~/src/serpent$ make
g++ -fPIC   -c -o bignum.o bignum.cpp
g++ -fPIC   -c -o util.o util.cpp
g++ -fPIC   -c -o tokenize.o tokenize.cpp
g++ -fPIC   -c -o lllparser.o lllparser.cpp
g++ -fPIC   -c -o parser.o parser.cpp
g++ -fPIC   -c -o opcodes.o opcodes.cpp
g++ -fPIC   -c -o optimize.o optimize.cpp
g++ -fPIC   -c -o functions.o functions.cpp
g++ -fPIC   -c -o rewriteutils.o rewriteutils.cpp
g++ -fPIC   -c -o preprocess.o preprocess.cpp
g++ -fPIC   -c -o rewriter.o rewriter.cpp
g++ -fPIC   -c -o compiler.o compiler.cpp
g++ -fPIC   -c -o funcs.o funcs.cpp
g++ -fPIC   -c -o cmdline.o cmdline.cpp
cmdline.cpp: In function ‘int main(int, char**)’:
cmdline.cpp:62:54: error: ‘compileChunkToLLL’ was not declared in this scope
         std::cout << printAST(compileChunkToLLL(input), haveSec) << "\n";
                                                      ^
cmdline.cpp:83:58: error: ‘prettyCompileChunk’ was not declared in this scope
         std::cout << printTokens(prettyCompileChunk(input)) << "\n";
                                                          ^
cmdline.cpp:98:49: error: ‘compileChunk’ was not declared in this scope
         std::cout << binToHex(compileChunk(input)) << "\n";
                                                 ^
make: *** [cmdline.o] Error 1

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.