Genpyteal - Experiment to rewrite Python into PyTeal using RedBaron

Overview

genpyteal

Converts Python to PyTeal. Your mileage will vary depending on how much you deviate from the examples. Its quite easy to get an error by doing something not supported. However, it often still outputs useful PyTeal that you can then fix up.

If you appreciate this tool, you are welcome to send ALGOs to RMONE54GR6CYOJREKZQNFCZAUGJHSPBUJNFRBTXS4NKNQL3NJQIHVCS53M.

Installation

pip3 install genpyteal or pip install genpyteal

Warning: The scripts have python3 in them because that is what works on my system. It only works with Python 3. There might be some system where it needs to say python instead. If so, maybe just pull the code from the github repo to change it?

Usage

To generate PyTeal:

genpyteal thescript.py

To generate PyTeal and do syntax highlighting (requires pygmentize and boxes to be installed):

genpyteal thescript.py | niceout

To generate PyTeal and then TEAL:

genteal thescript.py

To show the AST (FST) of a Python program (uses RedBaron .help(), and requires ipython installed):

showast thescript.py

Supported constructs

statement list (= Seq), integer const ( = Int(n)), if/else, while, print (= Log), + ( = Concat(str1, str2) ), True/False (= 1/0), and/or/not ... (maybe something I am forgetting).

Details

You can use a subset of Python. For scratch variables, you will need to initialize them at the beginning of a function, such as x = 0 or s = "tom". It uses that to determine the type. Sometimes you may need to specify Bytes or Int still. Integer/string literals get Int/Bytes added automatically. You can use print instead of Log.

Name the main function app to indicate a stateful application contract, or sig for a LogicSig contract.

For transaction fields, you can leave off the parenthesis, e.g. Txn.sender instead of Txn.sender().

It will assume functions return uint64 unless you specify @bytes or there is no return, which will automatically insert @Subroutine(TealType.none)

If you want to print a number in the log, you can use the numtostr function I made:

from lib import util

def app():
  print("Your number is " + util.numtostr(100))

The best explanation is just to show the examples.

Examples

examples/bool.py

def app():
  amt = 15
  return amt > 10 and amt < 20 or amt == 0

examples/callscratch.py

def g(x):
    return 3

def f(n):
    return g(n)

def app():
    x = f(30)
    name = "Bob"
    print(name)
    return 100

examples/checkgroup.py

PAYTO = Addr('6ZHGHH5Z5CTPCF5WCESXMGRSVK7QJETR63M3NY5FJCUYDHO57VTCMJOBGY')
FEE = 10 * 1000000
ZERO = Global.zero_address()

def no_close_to(i):
  Assert( Gtxn[i].close_remainder_to == ZERO )

def no_rekey(i):
  Assert( Gtxn[i].rekey_to == ZERO )

def verify_payment(i):
  Assert( Gtxn[i].receiver == PAYTO and
          Gtxn[i].amount == Int(FEE) and
          Gtxn[i].type_enum == TxnType.Payment )
         
def app():
  Assert( Global.group_size == 2 )
  
  no_close_to(1)
  no_rekey(1)

  verify_payment(1)

  App.globalPut('lastPaymentFrom', Gtxn[1].sender)
  Approve()

examples/ifseq.py

def foo(b):
  x = b

def app():
  foo(10)
  if 1 == 1:
    return 1
  else:
    return 0

examples/inner.py

def pay(amount: uint64, receiver: bytes):
    Begin()
    SetFields({
        TxnField.type_enum: TxnType.Payment,
        TxnField.sender: Global.current_application_address,
        TxnField.amount: amount,
        TxnField.receiver: receiver
        })
    Submit()

def app():
    pay(10, Addr('6ZHGHH5Z5CTPCF5WCESXMGRSVK7QJETR63M3NY5FJCUYDHO57VTCMJOBGY'))
    result = 0
    if Txn.first_valid > 1000000:
        result = 1
    return result

examples/strargs.py

65: print("User " + name + " is at retirement age.") return 1 else: print("User " + name + " is still young.") return 0">
def app():
  name = ""
  name = Txn.application_args[0]
  age = Btoi(Txn.application_args[1])
  if age > 65:
    print("User " + name + " is at retirement age.")
    return 1
  else:
    print("User " + name + " is still young.")
    return 0

examples/swap.py

< Int(tmpl_fee) is_payment = Txn.type_enum == TxnType.Payment no_closeto = Txn.close_remainder_to == ZERO_ADDR no_rekeyto = Txn.rekey_to == ZERO_ADDR safety_cond = is_payment and no_rekeyto and no_closeto recv_cond = (Txn.receiver == tmpl_seller) and (tmpl_hash_fn(Arg(0)) == tmpl_secret) esc_cond = (Txn.receiver == tmpl_buyer) and (Txn.first_valid > Int(tmpl_timeout)) return (fee_cond and safety_cond) and (recv_cond or esc_cond)">
"""Atomic Swap"""

alice = Addr("6ZHGHH5Z5CTPCF5WCESXMGRSVK7QJETR63M3NY5FJCUYDHO57VTCMJOBGY")
bob = Addr("7Z5PWO2C6LFNQFGHWKSK5H47IQP5OJW2M3HA2QPXTY3WTNP5NU2MHBW27M")
secret = Bytes("base32", "2323232323232323")
timeout = 3000
ZERO_ADDR = Global.zero_address()

def sig(
    tmpl_seller=alice,
    tmpl_buyer=bob,
    tmpl_fee=1000,
    tmpl_secret=secret,
    tmpl_hash_fn=Sha256,
    tmpl_timeout=timeout,
):
    fee_cond = Txn.fee < Int(tmpl_fee)
    is_payment = Txn.type_enum == TxnType.Payment
    no_closeto = Txn.close_remainder_to == ZERO_ADDR
    no_rekeyto = Txn.rekey_to == ZERO_ADDR
    safety_cond = is_payment and no_rekeyto and no_closeto
    
    recv_cond = (Txn.receiver == tmpl_seller) and (tmpl_hash_fn(Arg(0)) == tmpl_secret)
    esc_cond = (Txn.receiver == tmpl_buyer) and (Txn.first_valid > Int(tmpl_timeout))

    return (fee_cond and safety_cond) and (recv_cond or esc_cond)

examples/usenumtostr.py

from lib import util

def app():
  print("The best number is " + util.numtostr(42))
  return True

examples/whilecallif.py

from lib import util

def proc(n):
  return n * 2

def acceptable(n, target):
  if n >= target:
    print("Acceptable. Diff is " + util.numtostr(n - target))
    return True
  else:
    return False

def app():
  total = 1
  i = 0
  while not acceptable(total, Btoi(Txn.application_args[0])):
    total = proc(total)
    i += 1
  return i

examples/whilesum.py

def app():  
  totalFees = 0
  i = 0
  while i < Global.group_size:
    totalFees = totalFees + Gtxn[i].fee
    i = i + 1
  return 1

lib/util.py

@bytes
def numtostr(num):
  out = "             "
  i = 0
  digit = 0
  n = num
  done = False
  while not done:
    digit = n % 10
    out = SetByte(out, 12-i, digit+48)
    n = n / 10		
    if n == 0: done = True
    i = i + 1
  return Extract(out, 12 - i + 1, i)
Owner
Jason Livesay
Jason Livesay
A guide to building basic malware in Python by implementing a keylogger application

Keylogger-Malware-Project A guide to building basic malware in Python by implementing a keylogger application. If you want even more detail on the Pro

Noah Davis 1 Jan 11, 2022
A quick script to spot the usage of Unicode Bidi (bidirectional) characters that could lead to an Invisible Backdoor

Invisible Backdoor Detector is a little Python script that allows you to spot and remove Bidi characters that could lead to an invisible backdoor. If you don't know what that is you should check the

SecSI 28 Dec 29, 2022
CVE-2022-23046 - SQL Injection Vulnerability on PhpIPAM v1.4.4

CVE-2022-23046 PhpIPAM v1.4.4 allows an authenticated admin user to inject SQL s

2 Feb 15, 2022
Patching - Interactive Binary Patching for IDA Pro

Patching - Interactive Binary Patching for IDA Pro Overview Patching assembly code to change the behavior of an existing program is not uncommon in ma

589 Dec 30, 2022
Get important strings inside [Info.plist] & and Binary file also all output of result it will be saved in [app_binary].json , [app_plist_file].json file

Get important strings inside [Info.plist] & and Binary file also all output of result it will be saved in [app_binary].json , [app_plist_file].json file

12 Sep 28, 2022
pybotnet - A Python Library for building Botnet , Trojan or BackDoor for windows and linux with Telegram control panel

pybotnet A Python Library for building botnet , trojan or backdoor for windows and linux with Telegram control panel Disclaimer: Please note that this

</oNion 181 Jan 02, 2023
A collection of intelligence about Log4Shell and its exploitation activity

Log4Shell-IOCs Members of the Curated Intelligence Trust Group have compiled a list of IOC feeds and threat reports focused on the recent Log4Shell ex

Curated Intel 172 Nov 17, 2022
Strapi Framework Vulnerable to Remote Code Execution

CVE-2019-19609 Strapi Framework Vulnerable to Remote Code Execution well, I didnt found any exploit for CVE-2019-19609 so I wrote one. :/ Usage pytho

Dasith Vidanage 7 Mar 08, 2022
User-friendly reference finder in IDA

IDARefHunter Updated: This project's been introduced on IDA Plugin Contest 2021! Why do we need RefHunter? Getting reference information in one specif

Jiwon 29 Dec 04, 2022
Fat-Stealer is a stealer that allows you to grab the Discord token from a user and open a backdoor in his machine.

Fat-Stealer is a stealer that allows you to grab the Discord token from a user and open a backdoor in his machine.

Jet Berry's 21 Jan 01, 2023
Repository for a project of the course EP2520 Building Networked Systems Security

EP2520_ACME_Project Repository for a project of the course EP2520 Building Networked Systems Security in Royal Institute of Technology (KTH), Stockhol

1 Dec 11, 2021
ThePhish: an automated phishing email analysis tool

ThePhish ThePhish is an automated phishing email analysis tool based on TheHive, Cortex and MISP. It is a web application written in Python 3 and base

675 Jan 03, 2023
LdapRelayScan - Check for LDAP protections regarding the relay of NTLM authentication

LDAP Relay Scan A tool to check Domain Controllers for LDAP server protections r

315 Dec 18, 2022
Dome - Subdomain Enumeration Tool. Fast and reliable python script that makes active and/or passive scan to obtain subdomains and search for open ports.

DOME - A subdomain enumeration tool Check the Spanish Version Dome is a fast and reliable python script that makes active and/or passive scan to obtai

Vadi 329 Jan 01, 2023
A python implementation of the windows 95 product key check.

Windows 95 Product Key Check Info: This is a python implementation of the windows 95 product key check. This was just a bit of fun and a massive 5 hou

11 Aug 07, 2022
Python Password Generator

This is a console-based version of a password generator written with Python. The program generates a password based on numbers of letters, numbers, and symbols specified by the user. This is a simple

p.katekomol 1 Jan 24, 2022
Log4j vuln fuzz/scan with python

Log4jFuzz log4j vuln fuzz/scan USE // it's use localhost udp server to check target vuln. python3 log4jFuzz.py [option] optional arguments: -u URL,

VVzv 3 Dec 22, 2021
Auerswald COMpact 8.0B Backdoors exploit

CVE-2021-40859 Auerswald COMpact 8.0B Backdoors exploit About Backdoors were discovered in Auerswald COMpact 5500R 7.8A and 8.0B devices, that allow a

6 Sep 22, 2022
JavaScript Raider is a coverage-guided JavaScript fuzzing framework designed for the v8 JavaScript engine

JavaScript Raider is a coverage-guided JavaScript fuzzing framework designed for the v8 JavaScript engine

105 Dec 05, 2022
an impacket-dependent script exploiting CVE-2019-1040

dcpwn an impacket-dependent script exploiting CVE-2019-1040, with code partly borrowed from those security researchers that I'd like to say thanks to.

QAX A-Team 71 Nov 30, 2022