Skip to content

Instantly share code, notes, and snippets.

@ilyar
Last active November 6, 2023 20:45
Show Gist options
  • Save ilyar/ab03a2a32d5e4dc42b78d203343bd3ba to your computer and use it in GitHub Desktop.
Save ilyar/ab03a2a32d5e4dc42b78d203343bd3ba to your computer and use it in GitHub Desktop.

Solidity to FunC

image

Requirements

Via Docker

alias docker-run='docker run --rm -i -v $(pwd):/src -w /src'
alias tvm-action='docker-run ghcr.io/ever-guild/tvm-action'
alias sold='tvm-action sold'
alias tonos-cli='tvm-action tonos-cli'
alias fift='tvm-action fift'
alias func='tvm-action func'

Usage

Step 1 sol > tvc

Create a file App.sol with the following content:

pragma ever-solidity >= 0.71.0;

contract App {
    function add(int a, int b) public pure returns (int) {
        return a + b;
    }
}

Compile solidity to tvc:

sold App.sol

Step 2 tvc > boc

Extract the code of the contract:

tonos-cli -j decode stateinit --tvc App.tvc | jq -r .code | base64 -d > App.boc

Step 3 boc > fift

Get function ID int value:

echo $((16#$(sold --function-ids App.sol | jq -r .add | cut -d'x' -f2)))

For signature add(int, int)(int), the function ID is 1347459865

Decompile App.boc:

echo '"Disasm.fif" include "App.boc" file>B B>boc <s disasm cr' | fift | grep -v 'ok' > App.fif

Result:

...
1347459865 PUSHINT
EQUAL
IFJMP:<{
  %COPY CODE%
}>
...

Step 4 fift > func

Create a file App.fc with the following content:

() recv_internal() { }

(int) code(int a, int b) asm """
  DROP
  6 GETGLOB
  76 THROWIFNOT
  OVER
  IF:<{
    256 LDI
    LDREF
    ENDS
    CTOS
  }>ELSE<{
    256 LDI
  }>
  256 LDI
  ENDS
  CALL:<{
    ADD
    256 FITS
  }>
  OVER
  IF:<{
    s3 PUSH
    CTOS
    2 LDU
    LDMSGADDR
    DROP
    NIP
    NEWC
    x{C} STSLICECONST
    STSLICE
    3494943513 PUSHINT
    130 UR
    256 STI
    ENDC
    0 PUSHINT
    SENDRAWMSG
  }>ELSE<{
    DROP
  }>
  IF:<{
    3 GETGLOB
    2 GETGLOB
    NEWC
    256 STU
    64 STU
    x{C_} STSLICECONST
    ENDC
    c4 POP
  }>
  0 THROW
""";

(int) add(int a, int b) method_id {
  return code(a, b);
}

Step 4 func > fift > boc

Compile func to boc:

func -SPA -o App.fif -W App.boc App.fc && fift App.fif

🤷🏻‍♂️ At this step, most likely you will get an error: Error interpreting file 'App.fif': App.fif:25: CALL:<{:-?, if this is not the case and you have successfully completed this impossible mission, please let me know in a comment, I will be glad for any of your feedback and suggestions 🖖🏻

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment