Skip to content

Instantly share code, notes, and snippets.

@DanielVF
Created March 30, 2022 16:26
Show Gist options
  • Save DanielVF/c058c73126ae584c806cbecadfc1a731 to your computer and use it in GitHub Desktop.
Save DanielVF/c058c73126ae584c806cbecadfc1a731 to your computer and use it in GitHub Desktop.
Code to visualize contracts
import nimPNG
import std/[times, os, strutils]
var bytecode: string = parseHexStr("6080604052600436106100cb5760003560e01c80638da5cb5b11610074578063d79779b21161004e578063d79779b21461029c578063e33b7de3146102d2578063f2fde38b146102e757600080fd5b80638da5cb5b146102125780639852595c14610230578063ce7c2ac21461026657600080fd5b806348b75044116100a557806348b75044146101a5578063715018a6146101c55780638b83209b146101da57600080fd5b806319165587146101195780633a98ef391461013b578063406072a91461015f57600080fd5b36610114577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033604080516001600160a01b0390921682523460208301520160405180910390a1005b600080fd5b34801561012557600080fd5b50610139610134366004610d0c565b610307565b005b34801561014757600080fd5b506001545b6040519081526020015b60405180910390f35b34801561016b57600080fd5b5061014c61017a366004610d29565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205490565b3480156101b157600080fd5b506101396101c0366004610d29565b6104c0565b3480156101d157600080fd5b50610139610738565b3480156101e657600080fd5b506101fa6101f5366004610d62565b61079e565b6040516001600160a01b039091168152602001610156565b34801561021e57600080fd5b506000546001600160a01b03166101fa565b34801561023c57600080fd5b5061014c61024b366004610d0c565b6001600160a01b031660009081526004602052604090205490565b34801561027257600080fd5b5061014c610281366004610d0c565b6001600160a01b031660009081526003602052604090205490565b3480156102a857600080fd5b5061014c6102b7366004610d0c565b6001600160a01b031660009081526006602052604090205490565b3480156102de57600080fd5b5060025461014c565b3480156102f357600080fd5b50610139610302366004610d0c565b6107ce565b6001600160a01b0381166000908152600360205260409020546103805760405162461bcd60e51b815260206004820152602660248201527f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060448201526573686172657360d01b60648201526084015b60405180910390fd5b600061038b60025490565b6103959047610d91565b905060006103c283836103bd866001600160a01b031660009081526004602052604090205490565b6108b0565b9050806000036104285760405162461bcd60e51b815260206004820152602b60248201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060448201526a191d59481c185e5b595b9d60aa1b6064820152608401610377565b6001600160a01b03831660009081526004602052604081208054839290610450908490610d91565b9250508190555080600260008282546104699190610d91565b90915550610479905083826108f8565b604080516001600160a01b0385168152602081018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056910160405180910390a1505050565b6001600160a01b0381166000908152600360205260409020546105345760405162461bcd60e51b815260206004820152602660248201527f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060448201526573686172657360d01b6064820152608401610377565b6001600160a01b0382166000908152600660205260408120546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa1580156105aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ce9190610da9565b6105d89190610d91565b9050600061061183836103bd87876001600160a01b03918216600090815260076020908152604080832093909416825291909152205490565b9050806000036106775760405162461bcd60e51b815260206004820152602b60248201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060448201526a191d59481c185e5b595b9d60aa1b6064820152608401610377565b6001600160a01b038085166000908152600760209081526040808320938716835292905290812080548392906106ae908490610d91565b90915550506001600160a01b038416600090815260066020526040812080548392906106db908490610d91565b909155506106ec9050848483610a16565b604080516001600160a01b038581168252602082018490528616917f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a910160405180910390a250505050565b6000546001600160a01b031633146107925760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610377565b61079c6000610a96565b565b6000600582815481106107b3576107b3610dc2565b6000918252602090912001546001600160a01b031692915050565b6000546001600160a01b031633146108285760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610377565b6001600160a01b0381166108a45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610377565b6108ad81610a96565b50565b6001546001600160a01b038416600090815260036020526040812054909183916108da9086610dd8565b6108e49190610df7565b6108ee9190610e19565b90505b9392505050565b804710156109485760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610377565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114610995576040519150601f19603f3d011682016040523d82523d6000602084013e61099a565b606091505b5050905080610a115760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610377565b505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610a11908490610afe565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000610b53826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610be39092919063ffffffff16565b805190915015610a115780806020019051810190610b719190610e30565b610a115760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610377565b60606108ee8484600085856001600160a01b0385163b610c455760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610377565b600080866001600160a01b03168587604051610c619190610e82565b60006040518083038185875af1925050503d8060008114610c9e576040519150601f19603f3d011682016040523d82523d6000602084013e610ca3565b606091505b5091509150610cb3828286610cbe565b979650505050505050565b60608315610ccd5750816108f1565b825115610cdd5782518084602001fd5b8160405162461bcd60e51b81526004016103779190610e9e565b6001600160a01b03811681146108ad57600080fd5b600060208284031215610d1e57600080fd5b81356108f181610cf7565b60008060408385031215610d3c57600080fd5b8235610d4781610cf7565b91506020830135610d5781610cf7565b809150509250929050565b600060208284031215610d7457600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b60008219821115610da457610da4610d7b565b500190565b600060208284031215610dbb57600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b6000816000190483118215151615610df257610df2610d7b565b500290565b600082610e1457634e487b7160e01b600052601260045260246000fd5b500490565b600082821015610e2b57610e2b610d7b565b500390565b600060208284031215610e4257600080fd5b815180151581146108f157600080fd5b60005b83811015610e6d578181015183820152602001610e55565b83811115610e7c576000848401525b50505050565b60008251610e94818460208701610e52565b9190910192915050565b6020815260008251806020840152610ebd816040850160208701610e52565b601f01601f1916919091016040019291505056fea2646970667358221220d24de0d5a29e1bd962c11319915369eb39e3f78b9dcb2697fdbee5e4ff7fcf3e64736f6c634300080d0033")
var w:int = 640
var h:int = 640
var lw:int = 140
var lh:int = 140
proc darken(x: char): char =
return char(int(x) - (int(x) div 10))
var img = newString(w * h * 4)
# Fill background
for p in countup(0, w * h):
img[p*3] = char(33)
img[p*3+1] = char(20)
img[p*3+2] = char(16)
let wrap = w * 3
var lx = 0
var ly = 0
var pushcounter = 0
var nextpushcounter = 0
for i, br in bytecode:
ly = ly + 1;
if ly > lh:
ly = 4;
lx = lx + 1;
if lx > lw:
break
if nextpushcounter > 0:
pushcounter = nextpushcounter
nextpushcounter = 0;
elif pushcounter == 0:
if char(br) >= char(0x60) and char(br) <= char(0x7F):
nextpushcounter = (int(br) - 0x60) + 2
if pushcounter > 0:
pushcounter -= 1;
# # New col on jumpdst
# if char(br) == char(0x5B) and pushcounter == 0:
# ly = 1;
# lx = lx + 1;
let x:int = 12 + lx * 4
let y:int = 12 + ly * 4
let p:int = (x + y * w) * 3
# Draw box
var r:char = char(0)
var g:char = char(0)
var b:char = char(0)
var isTerminal: bool = false
var isMoreTerminal: bool = false
var isStackManipulation: bool = false
# Check terminals
if pushcounter == 0:
if char(br) == char(0xF3): # Return
isTerminal = true;
isMoreTerminal = true;
elif char(br) == char(0xFD): # Revert
isTerminal = true;
isMoreTerminal = true;
elif char(br) == char(0x00): # STOP
isTerminal = true;
isMoreTerminal = true;
elif char(br) == char(0x56): # Jump
isTerminal = true;
if char(br) >= char(0x80) and char(br) <= char(0x9F): # Stack Ops
isStackManipulation = true
if pushcounter > 0:
r = char(207)
g = char(114)
b = char(55)
# r = char(40 + int(br) div 3)
# if br > char(0x7F):
# g = char(100 + int(br) div 3)
# else:
# g = char(152)
# b = char(216)
# if br == char(0):
# b = char(160)
# elif br == char(1):
# b = char(190)
# elif br == char(255):
# b = char(255)
if br == char(255):
r = char(248)
g = char(197)
b = char(132)
else:
r = char(200 + int(br) / 5)
g = char(114 + int(br) / 5)
b = char(55 + int(br) / 10)
img[p - wrap] = darken(r)
img[p+1 - wrap] = darken(g)
img[p+2 - wrap] = darken(b)
img[p+3 - wrap] = darken(r)
img[p+4 - wrap] = darken(g)
img[p+5 - wrap] = darken(b)
img[p+6 - wrap] = darken(r)
img[p+7 - wrap] = darken(g)
img[p+8 - wrap] = darken(b)
img[p] = r
img[p+1] = g
img[p+2] = b
img[p+3] = r
img[p+4] = g
img[p+5] = b
img[p+6] = r
img[p+7] = g
img[p+8] = b
img[wrap + p] = r
img[wrap + p+1] = g
img[wrap + p+2] = b
img[wrap + p+3] = r
img[wrap + p+4] = g
img[wrap + p+5] = b
img[wrap + p+6] = r
img[wrap + p+7] = g
img[wrap + p+8] = b
if pushcounter > 1:
img[wrap + wrap + p] = r
img[wrap + wrap + p+1] = g
img[wrap + wrap + p+2] = b
else:
img[wrap + wrap + p+0] = darken(r)
img[wrap + wrap + p+1] = darken(g)
img[wrap + wrap + p+2] = darken(b)
img[wrap + wrap + p+3] = r
img[wrap + wrap + p+4] = g
img[wrap + wrap + p+5] = b
if pushcounter > 1:
img[wrap + wrap + p+6] = r
img[wrap + wrap + p+7] = g
img[wrap + wrap + p+8] = b
else:
img[wrap + wrap + p+6] = darken(r)
img[wrap + wrap + p+7] = darken(g)
img[wrap + wrap + p+8] = darken(b)
else:
r = char(200)
g = char(200)
b = char(200)
if char(br) == char(0xFF):
r = char(200)
g = char(200)
b = char(0)
elif char(br) == char(0xFD): # Revert
r = char(255)
g = char(0)
b = char(0)
elif char(br) == char(0xF3): # Return
r = char(0)
g = char(255)
b = char(0)
elif char(br) == char(0x00): # Return
r = char(0)
g = char(255)
b = char(30)
elif char(br) == char(0x55): ## SSTORE
r = char(255)
g = char(160)
b = char(60)
elif char(br) == char(0x5B): # Jump DEST
r = char(60)
g = char(60)
b = char(60)
elif char(br) == char(0x56): # Jump
r = char(148)
g = char(50)
b = char(101)
elif char(br) == char(0x57): # Jump
r = char(148)
g = char(0)
b = char(101)
# elif char(br) >= char(0xf0):
# r = char(75)
# b = char(150 + (255 - int(br)) * 6)
# g = char(75)
elif char(br) >= char(0x80) and char(br) <= char(0x8F): # Stack Ops
r = char(60 + (0x9F - int(br)) * 4)
b = char(20 + (0x9F - int(br)) * 2)
g = char(20 + (0x9F - int(br)) * 2)
elif char(br) >= char(0x90) and char(br) <= char(0x9F): # Stack Ops
r = char(60 + (0x9F - int(br)) * 4)
b = char(20 + (0x9F - int(br)) * 3)
g = char(60 + (0x9F - int(br)) * 3)
elif char(br) == char(0xF1): # Call
r = char(40)
g = char(60)
b = char(255)
# else:
# r = char(br)
if isStackManipulation:
img[p+3 - wrap] = darken(r)
img[p+4 - wrap] = darken(g)
img[p+5 - wrap] = darken(b)
img[p+3] = r
img[p+4] = g
img[p+5] = b
img[wrap + p+3] = r
img[wrap + p+4] = g
img[wrap + p+5] = b
img[wrap + wrap + p+3] = r
img[wrap + wrap + p+4] = g
img[wrap + wrap + p+5] = b
else:
img[p - wrap] = darken(r)
img[p+1 - wrap] = darken(g)
img[p+2 - wrap] = darken(b)
img[p+3 - wrap] = darken(r)
img[p+4 - wrap] = darken(g)
img[p+5 - wrap] = darken(b)
img[p+6 - wrap] = darken(r)
img[p+7 - wrap] = darken(g)
img[p+8 - wrap] = darken(b)
img[p] = r
img[p+1] = g
img[p+2] = b
img[p+3] = r
img[p+4] = g
img[p+5] = b
img[p+6] = r
img[p+7] = g
img[p+8] = b
img[wrap + p] = r
img[wrap + p+1] = g
img[wrap + p+2] = b
img[wrap + p+3] = r
img[wrap + p+4] = g
img[wrap + p+5] = b
img[wrap + p+6] = r
img[wrap + p+7] = g
img[wrap + p+8] = b
img[wrap + wrap + p] = r
img[wrap + wrap + p+1] = g
img[wrap + wrap + p+2] = b
img[wrap + wrap + p+3] = r
img[wrap + wrap + p+4] = g
img[wrap + wrap + p+5] = b
img[wrap + wrap + p+6] = r
img[wrap + wrap + p+7] = g
img[wrap + wrap + p+8] = b
if isTerminal:
img[wrap + wrap + p - 3] = r
img[wrap + wrap + p - 2] = g
img[wrap + wrap + p - 1 ] = b
img[wrap + wrap + p+9] = r
img[wrap + wrap + p+10] = g
img[wrap + wrap + p+11] = b
if isMoreTerminal:
ly = 1;
lx = lx + 1;
elif isTerminal:
ly += 2;
# ly = 1;
# lx = lx + 1;
let filename = format("out/zar-$1.png", getTime())
echo filename;
var success = savePNG24(filename, img, w, h);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment