EtherScripter - a visual smart contract builder



  • ethergrokethergrok USMember Posts: 25
    I find it useful for my studies to have the "Show Blocks" view open on one screen, (if you have multiple monitors), and to have the "Show LLL" view, or canvas, open on another screen. I can then inspect the LLL code as I view the visual builder development environment. Your "Toolbox" drop down menu is filled with some wonderful goodies, I really, really like this. I see that this tool would allow me to present to an audience the construction of a contract where the audience would then have the ability to understand architecture and program flow at a level which is then approachable with an audience of power users, and developers who do not use LISP like languages or lower level languages. May I encourage you to create a login and user base so we can save our work as projects, I think that is the next, much needed step.

    I can't say enough how powerful a feature where several people could whiteboard and share the building of a contract together would be. If people around the world could build contracts together, whiteboard, that would be extremely powerful. And I just don't see the bitcoin development ecosystem being able to do this at any level of elegance, and your application is going to set the bar for smart contract development as the potential user base has the potential to be magnitudes larger than the traditioinal, advanced developers love of "notepad", (s), :)

    Your ability to provide a toolset, a naming convention for operations, etc., that accurately parallels the development of LLL for writing smart contracts in Ethereum is a gift. This is obviously what you do and do well, thanks for doing this for Ethereum.
  • mode80mode80 Member Posts: 64 ✭✭
    @ethergrok , those are good ideas. I'll add "split screen" to the feature list. The Toolbox menu is exactly for the purpose you describe. Save, sign-in and "whiteboard collaboration" are all on the list. Making hard stuff easy is my favorite kind of challenge. Glad you like it.
  • ethergrokethergrok USMember Posts: 25
    I'll vote for putting "split screen" at the top of the list along with sign-in/save work/projects.
  • mode80mode80 Member Posts: 64 ✭✭
    Split-screen now available under the View menu. Same URL
  • ethergrokethergrok USMember Posts: 25
    Split-screen is a very nice feature. The user can now drag a visual building block onto the canvas and see the LLL code associated with that block in the code view, and watch the LLL code change as the drop down menu in a block is manipulated to change the code associated with that block. Good work.
  • BluefinBluefin Member Posts: 47
    Left /Right scroll bar at the bottom needs to be there in case we need to scroll it.
  • BluefinBluefin Member Posts: 47
    edited April 2014
    There is no Gas price function in the program yet, I presume. The other thing that you may want to incorporate is to be able to plonk an LLL program into the pane and convert it into a building block. That would be neat for "reverse" engineering.

    I am a non-programmer per se, but I do have some programming knowledge from some 30 years ago. I must say, it is user friendly enough for a person that has some appreciation of programming to work on this.

    I do not know most of the functions as there is insufficient documentation to understand all its functions.

    I will be more than happy to write that part for you, if you allow me and if you have the patience to run through the thing with me.

    I see your work as the most progressive of the lot in terms of getting the know-how to the masses.

    The rest of the developers' work in this forum, although I know they are doing a lot, have been too nebulous for the man on the street like me.

    Good one!
  • sdpalleysdpalley Member Posts: 15
    This is very interesting and I'd love to be involved in the beta test. I'm a practicing lawyer with some coding background (though definitely not a pro). As lawyers, we spend too much time recreating the same or similar contract documents and pleadings for court filings. Something at a higher level than legal zoom that allows modular construction of legal docs -- particularly using the lawyer's existing forms library -- would be very useful.
  • mode80mode80 Member Posts: 64 ✭✭
    Thanks @Bluefin. The core developers are concentrating on the low level stuff which is still an early work in progress. I expect there will be more help once things stabilize.

    That is also true for EtherScripter. I'd like to include an interactive tutorial and real documentation eventually. I'd be happy for help once its ready for that.

    In the meantime you can watch the latest walkthrough video at

    Gas is supported in EtherScripter to the extent that it is in Ethereum's POC-4. You call a different contract with a gas (fee) budget using the "send" or "call" block, which you can find under the Tools menu.

    Everything available in LLL is available via EtherScripter.
  • mode80mode80 Member Posts: 64 ✭✭
    Hi @sdpalley. Etherscripter is now available for everyone to bang on at

    You can see one person's take (mine) on how Ethereum compares to traditional law here:

    A fill-in-the blank repository ala Legal Zoom for smart contracts is still in the future, but I expect that's bound to happen.
  • BluefinBluefin Member Posts: 47
    I came across this very interesting cosign multisig program by mquandalle. I believe it is LLL and it appears to differ a bit vis-a-vis Gavin's. Take a look here:

    Of particular note are lines 41 to 43. How do I translate that to your Etherscripter?

    The other one of note is line 83. I cannot figure out how to do that in Etherscripter. It just beats the hell out of my slow mind to do that at all.

    I note you do not have bitwise logic, right?
  • mode80mode80 Member Posts: 64 ✭✭
    edited April 2014
    Ah. Yes, that example targets PoC-5, which has new bitwise operators. The latest EtherScripter targets PoC-4 (what you get now when you download the compiled AlethZero from

    Lines 41 to 43 are "sstore" operations written in abbreviated form. In LLL, the form (sstore 1 2) stores the value 2 at slot 1. LLL also supports a cryptic abbreviation of same written as [[1]] 2. That's what you're seeing there.

    EtherScripter has corresponding blocks:
    [in save slot ___ put ___]
    @___ = ___]
    respectively. My abbreviation is also more cryptic, which is why it's hidden by default. You can show it using the Toolbox menu.

    Line 83 is a for loop, which you can also find under the Toolbox menu. LLL's for loop has 4 pieces which you can see better written like this (with comments):

    () ;; initialize the loop. in this case do nothing.
    @votes ;; end the loop when "false". considered "false" when @votes goes to 0
    [nbVotes] (+ @nbVotes 1) ;; increment the nbVotes variable for later
    [votes] (& @votes (- @votes 1)) ;; the loop body

    The loop body above is a bit-counting hack invented by computer scientist Brian Kernighan. Google him, but don't feel bad if you don't immediately understand it.

    In fact don't feel bad if your find LLL hard to understand in general. Lisps are notoriously hard to read. EtherScripter tries to make it approachable. Also Serpent.
  • BluefinBluefin Member Posts: 47
    @mode80, thanks for the clear up. I await eagerly for you to roll out your POC-5 and keep abreast with the development till launch date. At least I know I have something solid to work on by launch date. ;-)
  • ADSactlyCryptoADSactlyCrypto Vineland, OntarioMember Posts: 7 ✭✭
    I would like to Beta Test this to help out.
  • BluefinBluefin Member Posts: 47
    edited May 2014
    @mode80‌, in your etherscripter example on Insurance Policy you have this line:

    (sstore CUSTOMER_BALANCE (+ CUSTOMER_BALANCE (callvalue)))

    I am a bit confused. Shoudn't it be :
    (sstore CUSTOMER_BALANCE (+ @CUSTOMER_BALANCE (callvalue)))

    If it is not then I am confused with the differences in the usage of

    CUSTOMER_BALANCE ( my understanding: Variable Name)
    @CUSTOMER_BALANCE ( my understanding: Value in the Variable Name)
    @@CUSTOMER_BALANCE ( my understanding: Value pointed to by the value in the Variable Name)

    I believe "in save slot @CUSTOMER_BALANCE" has the same value and referencing the same thing as "@@CUSTOMER_BALANCE", right?

    Just trying to understand it.

    Would be good if you left the old examples there. Good for learning and referencing for the unfamiliar.

    I must say, I am getting the hang of programming LLL through your site.

    Thank you!
  • mode80mode80 Member Posts: 64 ✭✭
    Good catch...that's a bug.

    But the line should read:
    (sstore CUSTOMER_BALANCE (+ @@CUSTOMER_BALANCE (callvalue)))

    CUSTOMER_BALANCE by itself is the same as the number 32 (... or whatever number was auto-assigned to that label by LLL). It's a human-friendly way to reference an auto-assigned number.

    @CUSTOMER_BALANCE is equivalent to (mload CUSTOMER_BALANCE). It's "the contents of the memory at slot 32". (in this example)

    @@CUSTOMER_BALANCE is equivalent to (sload CUSTOMER_BALANCE). It's "the contents of storage at slot 32".

    So one @ to grab from memory two @@s to grab from storage.

    Since that line is supposed to grab the contents from storage and increment, it should have two @@s.

    In EtherScripter, it's the [data at save slot ____] block I should have used there -- or the synonymous [@@ ___] abbreviation block.

    I can see why you might expect that two @@s does twice what one @ does once, but its not so in LLL.

    I'm glad EtherScripter is helping you learn. Sorry for the confusing bug.
  • BluefinBluefin Member Posts: 47
    @mode80, Thanks for the explanation.

    So memory is equal to saying that its state of value exists only during the execution of the contract and is non retentive as opposed to Storage which can be carried forward to the next execution of the contract?

    Is there an array function and floating point numbers? Don't seem to see that.

  • mode80mode80 Member Posts: 64 ✭✭
    yes, memory = contract duration, storage = theoretically forever

    EtherScripter calls these "temp slot" and "save slot" respectively. The hope is that those terms are more intuitive to non-programmers. (Or at least more compact than alternatives.)

    There is no array function per say but check out the "Swear Jar" sample for how you can use a sequence of memory slots in place of an array.

    Ethereum protocol does not support floating point and probably never will. (Floating point implementations across platforms are surprisingly inconsistent and would break Ethereum's need for deterministic consensus.) What you do instead is essentially 5th grade fractions.. multiply by the numerator then divide by the denominator. Your result will be "rounded down" to the nearest whole number. Where that's not precise enough, work in smaller units (e.g. wei instead of ether).
  • BluefinBluefin Member Posts: 47
    @mode80, Thanks for the clarification. Your answers have been of great help to my understanding.

    So what you are saying is that if a division results in a value with decimal, the output will essentially be just the integer portion of the result, e.g., the output will only be, say 5, instead of the actual result, 5.635?
  • mode80mode80 Member Posts: 64 ✭✭
    ya.. 7 divided by 4 equals... 1
  • BluefinBluefin Member Posts: 47
    @mode80, thanks for all the clarifications. You have given me great insight. What remains is a couple more things:

    What is [contract address], i.e., (address)? Is it the address of the current contract address where it is being executed?

    What is [self-destruct to ___] and how does that work? Is it like a [stop] function? I presume [stop] means jump out of the contract and skip execution of the rest of the codes following it.
  • mode80mode80 Member Posts: 64 ✭✭
    yes, (address) is current contract address
    [self destruct to __] destroys the contract, and empties its balance to the address provided in the blank

    Docs during this rapid development phase are pretty scattered but the best hints are from:

    and the Appendix G.2 table from Gavin's yellow paper

    This describes lower level instructions but you'll recognize lots of them and the descriptions can be helpful.
  • BluefinBluefin Member Posts: 47
    @mode80, I realised that after posting the above, but still some of them are so cryptic. Anyway, thanks a lot.
  • BluefinBluefin Member Posts: 47
    @mode80, Question.

    In your "Send to Address" Block, you have start slot and end slot. If my start slot is 0 and end slot is 7, I am effectively sending 8x32=256 bytes of data, isn't it? But your LLL is (call 0x0 0 0 0 224 0 0). Shouldn't the 224 be 256 instead? It appears that Gavin's POC V says that it is "7-1" which is effectively 224 which is correct. But I believe for Block Scripting you may want to "increment" that so that it is more consistent with what we think it is. I am not sure if I interpreted it correctly anyway.

    I am puzzled here because if I used "Call Address" and attempt to send 256 bytes starting from 0, the LLL is (call 0x0 0 0 0 256 0 0), which is more consistent.
  • mode80mode80 Member Posts: 64 ✭✭
    The [call] and [send] blocks are something of a rough edge that I'm still debating how to smooth.

    A "slot" is a chunk of 32-bytes. For memory and storage operations, LLL deals in "slots". But for contract inputs, it deals in bytes (starting in POC4). I don't like this. So I provide a block that takes slots and translates it to bytes for the user. That way it's consistent and the user (ideally) never has to deal with bytes.

    The [send] block currently takes as inputs the start slot and the -end slot- (non-inclusive) for the data you're sending. Ditto for accepting reply data. It translates all this for you down to the starting point and the -data length- measured in bytes.

    Unfortunately, there might be a contract that expects, for example, a packed list of 20-byte addresses. Then to call it, it's unavoidable that the user must deal with bytes. So I regrettably provide a block for that too:

    The [call] block mirrors LLL's underlying (call) statement. So it takes as inputs the starting point and the -length- of the data you're sending -measured in bytes-.

    I realize having these two blocks with subtly different inputs is confusing. I'd really like to just nuke the [call] block and provide only [send], but if you ever need [call] nothing else will do.

    The [send] block currently interprets "end slot" as the marker for where the data ends, but does not include it in the sent data. It seems you expected it to be "up to and including" the end slot data.

    Upon reflection, your assumption is more intuitive, so I will change that. But I'll wait to include it with Etherscripter 0.5.0, along with the other breaking changes required for compatibility the upcoming POC-5 release.
  • BluefinBluefin Member Posts: 47
    @mode80, I don't think you can nuke [call]. But nevertheless, I think it is pretty clear with your [call] and [send] so long as you have defined what a slot is in the help documentation later. I don't have a problem with that.

    And yes, I believe it is more intuitive if the meaning of start and end is to be taken literally as both starting and ending because you included the start slot and did not include the end slot. But then again if this is documented later, there shouldn't be any confusion. I just needed clarification if what I thought was right earlier on.

  • BluefinBluefin Member Posts: 47
    @mode80‌, maybe you want to consolidate the [call] and [send] into one block function. Just give the "end slot" and "with byte length" as drop down options in the one block like how you do for the others. That is neater and less confusing.
  • mode80mode80 Member Posts: 64 ✭✭
    Hey, good idea. I'll definitely do that.
  • mode80mode80 Member Posts: 64 ✭✭
    I'm pushing a release now that documents all the blocks with tooltips. Just hover over the block and it describes what it does. Let me know if you see any that are especially confusing or unclear.
  • BluefinBluefin Member Posts: 47
    @mode80‌, I note that the [data at input slot ___] does not take in a mathematical function such as 128+(i*32).

    It would be cool to do that so that I can do a while loop to read values off the input slot stack.
Sign In or Register to comment.