Taster Language

Taster is the domain-specific language (DSL) for ChainRunner.

Translating the human language (or intention) to computers require complex techniques in programming, especially in blockchain and DeFi. Users who are looking to “swap ETH to USDT” or “short ETH with 2x leverage” would need to go through multiple DeFi platforms, or rather, million lines of coding.

To solve these problems, Taster was developed. Taster helps ChainRunner interpret our language and execute blockchain-based tasks. This type of high-level programming language supporting a particular set of tasks in a specific domain is called a domain-specific language (DSL). DSL allows for increased connectivity among services and is easily comprehensible for anyone who desires to use it.

Taster automatically transpiles needed features into Solidity-based smart contracts, allowing developers to flexibly integrate DeFi protocols, such as Uniswap or Compound. If you are familiar with Python or Javascript, refer to the Taster procedure reference documentation to start using Taster.

Overview

  • Taster includes four different components: value, control statement (if, for), command, and procedure (function)

  • Lines of Taster can be used on Gourmet’s REPL driver or on separate files (scenarios)

  • Control statement and few syntaxes only run when written as scenarios

  • List of REPL help commands

Value

  • Use let to save value

  • Use : to specify type

  • If value is not needed, use _ to bind

let i = 1;
let i = 1:int256;
let s = "string";
let a = "0x32323241828761" : address;
let by = "101010100101" : bytes;
let by2 = "101" : bytes4;
let b = true;
let _ = fnWithoutReturnValue ();
  • All binded labels support toString()

GOURMET> i.toString()
"1"

​GOURMET> s.toString()
""string""

​GOURMET> a.toString()
""0x32323241828761""​

GOURMET> by.toString()
""101010100101""

​GOURMET> by2.toString()
""101""

​GOURMET> b.toString()
"True"

​GOURMET> print("myAddress : " + a.toString())
"myAddress : "0x32323241828761""

​GOURMET>

  • All binded labels support getType()

    • This shows a simplified version of the abbreviated type

GOURMET> let a = 1 usdt;

GOURMET> a.getType ()
currency

GOURMET> let b = ""

GOURMET> b.getType ()
string

GOURMET> let c = true

GOURMET> c.getType ()
bool

GOURMET> let d = 1

GOURMET> d.getType ()
number

GOURMET>

Procedure (function)

  • Taster supports function-like procedures like all general languages

  • Refer to the Procedure page for details

proc testProcedure (a, b) {
  let c = a;
  let d = b;
  let e = c + d;  
  
  proc isOdd (a) {
    if (a % 2 != 0) {
      return true;
    } else {
      return false;
    }
  }  
  
  let returnValue = isOdd (e);   
  return returnValue;
}

dry

Use dry to call functions or procedures of deployments. This will not affect the blockchains itself.

  • Ganache must be installed and both public and private keys must be set to env.account

  • env.blockchain is the Ganache blockchain of the dry call function or procedure

proc mySwap() {  
  let receivedAmount = swap(...);  
  return receivedAmount;
}

​let receivedTokens = dry mySwap();
print("If you swap now, you can get as much as " + receivedTokens.toString());​
dry someBuiltIn();
dry someDeployment.someFunc();

Type

  • Supports the following types: bool, string, address, bytes, number, array, tuple, solution, deployment, ganache

Bool

  • Supports ture and false

GOURMET> let isTrue = true;
GOURMET> let isFalse = false;

String

  • Supports string

GOURMET> let str = "hello";
GOURMET> let str2 = str + " " + "world";

Address

  • Supports address types

  • Used the same as String

GOURMET> let usdtAddr = "0xdAC17F958D2ee523a2206206994597C13D831ec7";

Bytes

  • Supports Bytes types

  • Used the same as String

GOURMET> let b = "0x123123123" 

Number

  • Supports number types

  • Define the types int[8-256], uint[8-256] explicitly

  • If the type is not specified, the type is literal

GOURMET> let i = 1;
GOURMET> let i = 1:uint8;
GOURMET> let i = 1:int256;

  • Supports int types and number types such as Float and Currencies

  • Float types will return up to 6 decimal places only, but are fully stored up to 18 decimal places

GOURMET> 1.1
1.100000

GOURMET> 0.00001
0.000010

GOURMET> 0.000000001
0.000000

GOURMET> 0.000000001 * 10000000
0.010000

GOURMET>

  • Currency types represent the amount of coins or tokens on the blockchain networks. The decimal palces for each currency type displayed are the same as the decimal places for the underlying coin or token. (e.g. USDT(Tether) on Ethereum has 6 decimal places)

  • You must use unit types with network information (e.g., usdt_eth) for same tokens that have defferent decimals per each blockchain.

GOURMET> 1 usdt
Error : Node is empty.

GOURMET> 1 usdt_eth
1.000000 USDT

GOURMET> 1.000001 usdt_eth
1.000001 USDT

GOURMET> 1.0000011 usdt_eth
Error : The number below the decimal point is too large. (1, 11)~(1, 18)

GOURMET> env.blockchain.set ("http://localhost:8545");
Update Blockchain Node: http://localhost:8545 (Ethereum mainnet)

GOURMET> 1 usdt
1.000000 USDT

  • Type of UINT

    • BNB | BFC | BIFI | DAI | ETH | LINK | USDT6 | USDC6 | USDT18 | USDC18 | USDT | USDC | WBTC | BTCB

    • More will be added to the above list


GOURMET> 1.000001 usdt_eth
1.000001 USDT

GOURMET> 1.0000011 usdt_eth
Error : The number below the decimal point is too large. (1, 11)~(1, 18)

GOURMET>GOURMET> 1 bnb
1.000000 BNB

GOURMET> 1 BNB
1.000000 BNB

GOURMET> 1bnb
1.000000 BNB

GOURMET> 1.123 bnb
1.123000 BNB

GOURMET> 0.0001 bnb
0.000100 BNB

GOURMET>

Array

  • Declaration or indexing element

GOURMET> let a = [1, 2];
GOURMET> let b = a[0];
GOURMET> let c = a[1];
  • Chainging the values of an array is not possible

GOURMET> let a = [1, 2];~~let a[0] = 0     // 지원 안함
  • method

    • length : returns the length of an array

Tuple

  • Declaration or indexing elements

GOURMET> let t = (1, "a")
GOURMET> let (t1, t2) = t
GOURMET> let (_, t3) = t

Solution

  • Created through gen cmd only

GOURMET> let bifiBoostSolution = gen("sample/contracts/BifiBoost.sol", "0.6.12");
GOURMET> let bifiLauncherSolution = gen("sample/contracts/BifiLauncher.sol", "0.6.12");

Method

Solution tpes support the following methods:

  • [Solution].compile(optimize: false)

    • Compiles the solution

GOURMET> let bifiBoostSolution = gen("sample/contracts/BifiBoost.sol", "0.6.12");
GOURMET> bifiBoostSolution.compile ();
GOURMET> bifiBoostSolution.compile (optimize: true);

  • [Solution].[contractName]

  • [Solution].[contractName].construct

    • Deploys a specific contract of the solution

GOURMET> let bifiBoost = bifiBoostSolution.BifiBoost();
GOURMET> let bifiBoost = bifiBoostSolution.BifiBoost.construct();

  • [Solution].[contractName].gasEstimate

    • Computes the estimated gas fee when deploying the contract

    • You can find the actual amount of gas used by mulitplying the returned value and gasPrice

​GOURMET> let testSolution = gen ("/Prelude/contracts/sample.sol", "0.6.12");

GOURMET> testSolution.compile ();
Solution <sample, 0.6.12> (is compiled)​

GOURMET> let helloWorld = testSolution.HelloWorld (1, "0x010101");
'HelloWorld' was deployed.
'HelloWorld' deploy fee: 4985120000000000.

​GOURMET> testSolution.HelloWorld.gasEstimate (1, "0x010101");
249256

​GOURMET> testSolution.HelloWorld.gasEstimate (1, "0x010101") * env.defaultGasPrice.get ()
4985120000000000​

GOURMET>

In the example above, the estimated gas fee to deploy HelloWorld contract is 249256. Multiply the value with the default gas price to compute the amount of gas used. If the gasPrice is 20000000000 (e.g. the default gasprice of ganache), 249256 * 20000000000 = 4985120000000000​

Deployment

  • Direct declaration is not possible, and can be created through deploy or reg cmd.

​GOURMET> let bifiBoostSolution = gen("sample/contracts/BifiBoost.sol", "0.6.12");

GOURMET> bifiBoostSolution.compile ();​

GOURMET> let bifiBoost = bifiBoostSolution.BifiBoost(); // Deployment created by deploying the context.
'BifiBoost' was deployed.
'BifiBoost' deploy fee: 43837920000000000.

GOURMET> let bi = reg ("0x602C71e4DAC47a042Ee7f46E0aee17F94A3bA0B6", "/Prelude/ABI/ERC20.ABI.json"); // reg cmd을 통해 생성한 Depolyment

Method

Deployment types support the following methods:

  • [Deployment].getAddress ()

    • Returns the deployed contract address

GOURMET> let router = uniswapV2.router02.getDeployment()

​GOURMET> router.getAddress()
"0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D"

  • [Deployment].getEventByHash([event identifier], txhash: string)

    • Calls the specified event from the deployed contract with txHash

GOURMET> d.idFunction (1000)
'idFunction(uint256)' send transaction fee : 451100000000000.
"0xaa16bcf74139d108c7c78964fb56ca06593bba521bd50ce53e805f8188d33b2d"

​GOURMET> d.getEventByHash(IdEvent, "0xaa16bcf74139d108c7c78964fb56ca06593bba521bd50ce53e805f8188d33b2d")
Block Number     : 12552789
Event Name       : IdEvent
Transaction Hash : 0xaa16bcf74139d108c7c78964fb56ca06593bba521bd50ce53e805f8188d33b2d
Event Value      : 1000​unit

  • [Deployment].getEventByRange([event identifier], first: num, last: num)

    • Calls the specified event from the deployed contract within the specified range of the block numbers

    • Returns the event deployed between the first and last block

    • the 0 on the first and last represents the fallowing:

      • the 0 on the first block represents the deployed block

      • the 0 on the last block represents the last block number of the using blockchain

GOURMET> d.idFunction (1000)
'idFunction(uint256)' send transaction fee : 451100000000000.
"0xaa16bcf74139d108c7c78964fb56ca06593bba521bd50ce53e805f8188d33b2d"

​GOURMET> d.getEventByRange(IdEvent, 0, 0)
Block Number     : 12552789
Event Name       : IdEvent
Transaction Hash : 0xaa16bcf74139d108c7c78964fb56ca06593bba521bd50ce53e805f8188d33b2d
Event Value      : 1000​unit

​GOURMET> d.getEventByRange(IdEvent, 0, 12552789)
Block Number     : 12552789
Event Name       : IdEvent
Transaction Hash : 0xaa16bcf74139d108c7c78964fb56ca06593bba521bd50ce53e805f8188d33b2d
Event Value      : 1000​unit

​GOURMET> d.getEventByRange(IdEvent, 12552789, 12552789)
Block Number     : 12552789
Event Name       : IdEvent
Transaction Hash : 0xaa16bcf74139d108c7c78964fb56ca06593bba521bd50ce53e805f8188d33b2d
Event Value      : 1000​unit

​GOURMET> d.getEventByRange(IdEvent, 12552789, 0)
Block Number     : 12552789
Event Name       : IdEvent
Transaction Hash : 0xaa16bcf74139d108c7c78964fb56ca06593bba521bd50ce53e805f8188d33b2d
Event Value      : 1000​unit

  • [Deployment].[contract function identifier].call ()

  • [Deployment].[contract function identifier].send ()

    • Calls the contract function. Receives the function name (not string) and last of factors. call returns the reuturn value of the function and send returns the hash of the transaction.

let bal_tx = ctr_yeh.balanceOf.call (sender);
let bal_rx = ctr_yeh.balanceOf.call (receiver);
let txhash = ctr_yeh.transfer.send (receiver, 33);
​let balanceOfSomeone = ctr_bfc.balanceOf.call { Value = 10; Gas = 10 } ("": address);

  • [Deployment].[contract function identifier].gasEstimate ()

    • Computes the estimated gas fee when sending the contract function

    • You can find the actual amount of gas used by multiplying the returned value and gasPrice

GOURMET> let testSolution = gen ("/Prelude/contracts/sample.sol", "0.6.12");

GOURMET> testSolution.compile ();
Solution <sample, 0.6.12> (is compiled)

​GOURMET> let helloWorld = testSolution.HelloWorld (1, "0x010101");
'HelloWorld' was deployed.
'HelloWorld' deploy fee: 4985360000000000.​

GOURMET> helloWorld.sum.call (1, 2);

​GOURMET> helloWorld.sum (1, 2);
'sum(int256,int256)' send transaction fee : 433140000000000.0x80a7acc40a45b02fa29bd4c693727a0ce232bfd3269635bd0eaafe00c3b90cc8

​GOURMET> helloWorld.sum.gasEstimate (1, 2);
21657

​GOURMET> env.defaultGasPrice.get ()
20000000000

In the example above, the estimated gas fee of sum function is 21657. Multiply the value whti the default gas price to compute the amount of gas used.

21657 * 20000000000 = 433140000000000 (if ganache default gasFee is 20000000000)

  • [Deployment].[contract function identifier].delegateCall ()

    • Calls the target function through delegate call in the activated smart wallet

    • If a smart wallet is not activated, delegate call cannot be used

    • Transaction can be generated with EOA

GOURMET> env.activeWallet.set (wallet);
Smart wallet is activated : 0x2069d2392dc1b982fb8877b41d013fe1d757ff4f​

GOURMET> let t= gen ("Test.sol", "0.6.12");

​GOURMET> t.compile ();
Solution <Test, 0.6.12> (is compiled)

​GOURMET> let t = t.Test ();
'Test' was deployed.
'Test' deploy fee: 2712140000000000.

​GOURMET> t.print.delegateCall ()
'execute(address,bytes)' send transaction fee : 915520000000000.
0x6b1a93f68f09d7edce22014c448347b84b0494539ff897137d8e5aaa87dbd536

​GOURMET> env.activeWallet.set ()
Smart wallet is deactivated.

​GOURMET> t.print.delegateCall ()
Error : No active wallet to delegate call.

​GOURMET>
  • [Deployment].[contract function identifier] ()

    • Calls the contract function with argument

    • Determines call | send depending on state mutability of targetFunction

      • Calls for pure and view functions. Otherwise, sends

let bal_tx = ctr_yeh.balanceOf (sender);
let bal_rx = ctr_yeh.balanceOf (receiver);
let txhash = ctr_yeh.transfer  (receiver, 33);
​let balanceOfSomeone = ctr_bfc.balanceOf { Value = 10; Gas = 10 } ("": address);

Ganache

  • Direct declaration os not possible. Create though runGanache cmd.

Method

Ganache types supports the following methods:

  • [Ganache].getPort ()

    • Returns the port number of the address running Ganache-cli

GOURMET> let g = runGanache (port: 9005)
​GOURMET> g.getPort ()
9005​

  • [Ganache].getAccounts ()

    • Returns an array of accounts available in ganache-cli

    • Obtains the specific account using the index of account array

GOURMET> let g = runGanache (port: 9005)
​GOURMET> g.getAccounts ()
(0) "0xe70ad162a76621473e380c1acff4a2caead3cb80" (1) "0x4983e7f658576e2bce6391c4442a919b5c8a05bd" (2) "0xa8fc2f9ef351d51d945c672f9a551422aaef2efd" (3) "0x631ba1fd131dfeba9e23e17a442034344c912643" (4) "0x6e6c268802291c5eaae75a7a32e208e6afdc5723" (5) "0x34c81e8f46dc1aef4a737c44144c9513164d2b3b" (6) "0x4e82b2b41ab7c72cd44976cb6177212baab710e9" (7) "0x00a09ea92164498c19008da42645824b440d5878" (8) "0x60f75023df10db8587ba4b39577ba9e3137c95ab" (9) "0x6e9a11677a3c8241be3779a94a6db66f895a392b" GOURMET> let accounts = g.getAccounts ()GOURMET> env.account.set (accounts[0])

  • [Ganache].stop ()

    • Ends the ganache-cli process

Operator

  • Support arithmetic operators, comparison operators, and logical operators

    • Only numeric value are used for arithmetic operators

      • Arithmetic operators : +, -, *, /, %, **(exponential)

      • Unary negation operator : -

    • Numbers, strings, and logical values are used for comparison operators

      • Comparison operators: ==, !=, <, >

    • Only logical values are used for logical operators

      • Logical operators: ||, &&, !(not)

    • Bit operator (shift, |, &, etc.) are not supported

    • + operators are used to connect strings

GOURMET> print("hello, " + "gourmet!")
"hello, gourmet!"

​GOURMET> let result1 = true;

GOURMET> let result2 = false;

GOURMET> let result3 = (result1 || result2) && true;

GOURMET> assert ((result1 || result2) && true);
Assert : True

GOURMET> let a = 10 + 20 * 0;

GOURMET> let b = (10 + 20) * 0;

GOURMET> let c = (10 + 20) / 3;

GOURMET> let d = (10 + 20) % 7;

GOURMET> let e = a == b;

GOURMET> let f = (a == b) && (10 == 10);

GOURMET> assert (a == b);
Assert : False

GOURMET> assert ((a == b) && (10 == 10));
Assert : False

GOURMET> 2 ** 101024

GOURMET> -1
-1

GOURMET> !true
False

GOURMET> let a = "a";

GOURMET> let b = "b";

GOURMET> let c = "a";

GOURMET> assert (a == b);
Assert : False

GOURMET> assert (a == c);
Assert : True

GOURMET> assert (b == "b");
Assert : True

​* Assert does not support arithmetic operations.
ex) assert (1 + 3) // not supported

Control Statement

if

  • Supports branching statement

  • Can access the variable of the parent branch

  • A new procedure cannot be declared in an if statement

  • if statement can be without else

  • if ([condition]) {[cmd list]} else {[cmd list]}

  • if ([condition]) {[cmd list]}

if (true) {
	let asd = 12313;  
	EEE ()            
	if (true) {    
		AAA.BBB.CCC.EEE ()    
		print("print asd");    
		print(asd);    
		if (true) {      
			AAA.BBB.CCC.EEE ()      
			print("print asd");      
			print(asd);              
		} else {}  
	} else {}
} else {}​

if (num == 1) {  return 1;}

for

  • Supports looping statement

  • Can access the variable of the parent (does not pass the procedure)

  • A new procedure cannot be declared inside the if statement.

  • Support infinite loops

    • In the case of infinite loops, exit the loop with return statement

  • condition :

    • ([var] in [array])

    • ([var] in [number] .. [number])

    • If there is no condition, it is an infinite loop

proc test () {  
    let a = 1;  
    let b = 2;  
    let arr = [a,b,3,4];  
    for (a in arr) {    
        for (b in arr) {      
            if (a == 2 && b == 4) {        
                return a + b;
            } else {}
        }  
    }  
    return 0;
}

​proc test2 (start, finish) {  
    let arr = [1,2,3,4];  
    for (i in start .. finish) {    
        for (b in arr) {      
            if (i == 2 && b == 4) {        
                return i + b;
            } else {}    
        }  
    }  
    return 0;
}

​​proc blockMiningChecker (before) {  
    for {    
        if (getBlockNumber () > before) {      
            print ("A new block has been mined.");
            // do something      
            return 0; // exit loop.
        } else {}
    }
}

Command

  • Various commands are supported on Taster

  • Use the help command to see the command list

help

  • Returns the command list

  • Find how to use each command using help [command]

GOURMET> help

[*] Current Gourmet commands (type 'help <command>' for more info):

 - aaveV2.flashloan.execute: 
 - abiEncode: ABI encode values.
 - abiEncodeWithSignature: ABI encode with function signature.
 - addBlocks: Add dummy blocks.
 - assert: Print an assert result
 - bifi.eth.getUserAmount:
 - bifi.token.getUserAmount: 
 - clear.all: Clear all context.
 - clear.procedures: Procedure list initialize
 - clear.variables: Clear all variable.
 - compound: 
 - compound.cEther.getAccountSnapshot: 
 - compound.cToken.getAccountSnapshot: 
 - dInfo: Show all deployment information.
 - deploymentInfo: Show all deployment information.
 - dinfo: Show all deployment information.
 - env: Show the environment information.
 - env.account.get: Get user account
 - env.account.set: Set Account.
 - env.activeWallet.get: Get active smart wallet
 - env.activeWallet.set: Activate the smart wallet.
 - env.blockchain.get: Get current Blockchain
 - env.blockchain.set: Set Blockchain Node.
 - env.caller.set: Register Caller contract.
 - env.defaultGas.set: Set Default Gas.
 - env.defaultGasPrice.set: Set Default GasPrice.
 - env.defaultValue.set: Set Default Value.
 - env.pragma.set: Set Pragma.
 - env.recipe.set: Set recipe server.
 - env.rpcTimeout.set: Set RPC connection timeout.
 - envInfo: Show the environment information.
 - erc20.create: 
 - evalStatus: Print the evaluation status (e.g., binded variables, ...)
 - gInfo: Show ganache process information.
 - ganacheInfo: Show ganache process information.
 - gen: Generate a solution
 - genSolution: Generate a solution
 - genSolutionTests: 
 - getAccount: Get user account
 - getActiveWallet: Get active smart wallet
 - getBalance: Get the balance of an address.
 - getBlockNumber: Returns the current block number.
 - getBlockchain: Get current Blockchain
 - ginfo: Show ganache process information.
 - help: Show the usage.
 - insert: Insert procedure
 - let: Declare a variable.
 - pInfo: Show procedure information.
 - pinfo: Show procedure information.
 - print: Print an expression.
 - procedureInfo: Show procedure information.
 - reg: Register a contract that has already been deployed.
 - regContract: Register a contract that has already been deployed.
 - run: Evaluate and print the result of Scenario
 - runGanache: Runs ganache-cli process
 - runScenario: Evaluate and print the result of Scenario
 - sInfo: Show all solutions information.
 - setAccount: Set Account.
 - setActiveWallet: Activate the smart wallet.
 - setBlockchain: Set Blockchain Node.
 - setCaller: Register Caller contract.
 - setDefaultGas: Set Default Gas.
 - setDefaultGasPrice: Set Default GasPrice.
 - setDefaultValue: Set Default Value.
 - setPragma: Set Pragma.
 - setRPCTImeout: Set RPC connection timeout.
 - setRecipe: Set recipe server.
 - sinfo: Show all solutions information.
 - sleep: Suspends the current thread for the specified amount of time.
 - smartWallet.auth.add: 
 - smartWallet.getCallerAddress: 
 - solutionInfo: Show all solutions information.
 - status: Print the evaluation status (e.g., binded variables, ...)
 - stopGanache: Stop ganache-cli process
 - test.uni: 
 - test.uni.addLiquidity: 
 - test.uni.removeLiquidity: 
 - test.uni.swapExactIn: 
 - test.uni.swapExactOut: 
 - this.getAddress(): Get a deployed address when generated
 - transfer: Transfer the specific amount of Ether to the address.
 - uniswapV2.factory: 
 - uniswapV2.router02:

clear

  • Reset the environmental variables or let binded values on Gourmet

  • Can be used only when using REPL for Gourmet

  • Autometically loads the procedure defined in Prelude after it is cleared

GOURMET> clearAll context has been cleared.

env

  • Return various environment values

GOURMET> env
[*] Environment information:
   - Recipe Address           : http://localhost:9001
   - Blockchain Node          : http://localhost:8545 (UnknownChain)
   - Account ID               : 0x3B35A606CA0f807aCB407924E1062dbC8432BB84
   - Account Key              : key is empty
   - Default GasPrice         : default gas price
   - Default Gas              : 6000000 wei
   - Default Value            : 0 wei
   - Experimental Pragma list : []
   - RPC connection timeout   : 0 Seconds
   - Log file                 : gourmet.log
   - Active smart wallet      : No active wallet.
   - Caller Address           : No Caller registered.

  • Returns or sets each of the environment values

env.recipe.set

  • Set the recipe server

GOURMET> env.recipe.set
Usage:        
  env.recipe.set (["Recipe Server URL"]);
  setRecipe (["Recipe Server URL"]);
  
​​GOURMET> env.recipe.set ("http://localhost:9001");
Update Recipe Server URL: http://localhost:9001
unit

env.account.set

  • Sets the account

  • Can set only the publicKey of the account

GOURMET> let publicKey = "0x8BAA3237cc980C0436Cd4d494Dd0Ac4a109F7706";​

GOURMET> let privateKey = "0x9d7c3ede1667fd74e7308b1304b96eb1ba4f3d7bcb08d3c6988ed1aa5c3e5bed";

​GOURMET> let acc = (publicKey, privateKey);

​GOURMET> env.account.set (acc);
Update Account:  
  Account ID : 0x8BAA3237cc980C0436Cd4d494Dd0Ac4a109F7706  
  Account Key: 0x9d7c3ede1667fd74e7308b1304b96eb1ba4f3d7bcb08d3c6988ed1aa5c3e5bed
unit

​GOURMET> env.account.set (publicKey, privateKey);
Update Account:  
  Account ID : 0x8BAA3237cc980C0436Cd4d494Dd0Ac4a109F7706  
  Account Key: 0x9d7c3ede1667fd74e7308b1304b96eb1ba4f3d7bcb08d3c6988ed1aa5c3e5bed
unit

​GOURMET> env.account.set (publicKey);
Update Account:  
  Account ID : 0x8BAA3237cc980C0436Cd4d494Dd0Ac4a109F7706
unit

​GOURMET>​​

env.account.get

  • Retrieves the account information. Return type is tuple.

​GOURMET> let publicKey = "0x8BAA3237cc980C0436Cd4d494Dd0Ac4a109F7706";

​GOURMET> let privateKey = "0x9d7c3ede1667fd74e7308b1304b96eb1ba4f3d7bcb08d3c6988ed1aa5c3e5bed";

​GOURMET> let acc = (publicKey, privateKey);

​GOURMET> env.account.set (acc);
Update Account:  
  Account ID : 0x8BAA3237cc980C0436Cd4d494Dd0Ac4a109F7706  
  Account Key: 0x9d7c3ede1667fd74e7308b1304b96eb1ba4f3d7bcb08d3c6988ed1aa5c3e5bed
unit

​GOURMET> env.account.get ();
("0x8BAA3237cc980C0436Cd4d494Dd0Ac4a109F7706", "0x9d7c3ede1667fd74e7308b1304b96eb1ba4f3d7bcb08d3c6988ed1aa5c3e5bed")

​GOURMET> env.account.set (publicKey, privateKey);
Update Account:  
  Account ID : 0x8BAA3237cc980C0436Cd4d494Dd0Ac4a109F7706  
  Account Key: 0x9d7c3ede1667fd74e7308b1304b96eb1ba4f3d7bcb08d3c6988ed1aa5c3e5bed
unit

​GOURMET> env.account.get ();
("0x8BAA3237cc980C0436Cd4d494Dd0Ac4a109F7706", "0x9d7c3ede1667fd74e7308b1304b96eb1ba4f3d7bcb08d3c6988ed1aa5c3e5bed")

​GOURMET> env.account.set (publicKey);
Update Account:  
  Account ID : 0x8BAA3237cc980C0436Cd4d494Dd0Ac4a109F7706
unit

​GOURMET> env.account.get ();
("0x8BAA3237cc980C0436Cd4d494Dd0Ac4a109F7706", "")

​GOURMET>​​

env.blockchain.set

  • Sets the blockchain node

  • Enters the address as string format

  • Can use the binded label withrunGanache cmd

GOURMET> env.blockchain.set ("http://localhost:8545");
Update Blockchain Node: http://localhost:8545
unit​

GOURMET> let g = runGanache()

​GOURMET> env.blockchain.set (g);
Update Blockchain Node: http://localhost:8545
unit

​GOURMET>​

env.blockchain.get

  • Retrieves the blockchain node. Return type is tuple

GOURMET> let bscMain = "https://bsc-dataseed.binance.org/";

GOURMET> let bscTest = "https://data-seed-prebsc-2-s1.binance.org";

​GOURMET> env.blockchain.set (bscMain);
Update Blockchain Node: https://bsc-dataseed.binance.org/ (BSC mainnet))

​GOURMET> env.blockchain.get ()
("https://bsc-dataseed.binance.org/", "BSC mainnet")​

GOURMET> let (addr, kind) = env.blockchain.get()

​GOURMET> let (addr, kind) = getBlockchain()​

GOURMET> print (addr + kind)
"https://bsc-dataseed.binance.org/BSC mainnet"

​GOURMET> print (addr)
"https://bsc-dataseed.binance.org/"​

GOURMET> print (kind)
"BSC mainnet"

​GOURMET>

env.defaultGas.set

  • Set the defaultGas when sending a transaction. The unit is wei.

GOURMET> env.defaultGas.set (200000);
Update DefaultGas: 200000
unit

​GOURMET> env
[*] Environment information:
   - Recipe Address           : http://localhost:9001   
   - Blockchain Node          : http://localhost:8545   
   - Account ID               : 0x8BAA3237cc980C0436Cd4d494Dd0Ac4a109F7706   
   - Account Key              : key is empty   
   - Default GasPrice         : default gas price   
   - Default Gas              : 200000 wei   
   - Default Value            : 0 wei   
   - Experimental Pragma list : []   
   - RPC connection timeout   : 100 Seconds   
   - Log file                 : gourmet.log

​GOURMET>​

env.defaultGasPrice.get

  • Returns the default GasPrice

  • If the target blockChain network is not set, gasPrice cannot be found

GOURMET> let bscMain = "https://bsc-dataseed.binance.org/";

​GOURMET> let ganache = runGanache (fork: bscMain, mnemonic: "brownie", hardfork: "istanbul");

​GOURMET> env.blockchain.set (ganache);
Update Blockchain Node: http://localhost:8546 (BSC mainnet))

​GOURMET> env.defaultGasPrice.get ()
20000000000​

GOURMET>

env.defaultGasPrice.set

  • Set the defaultGasPrice when sending a transaction

  • If gasPrice is 0, the default gasPrice of the node's blockchain network will be used

  • For ganache, the default gasPrice is 20 Gwei (20000000000 wei)

GOURMET> env.defaultGasPrice.set (100000000000);
Update DefaultGas: 100000000000 wei
unit

​GOURMET> env
[*] Environment information:
   - Recipe Address           : http://localhost:9001   
   - Blockchain Node          : http://localhost:8545   
   - Account ID               : 0x8BAA3237cc980C0436Cd4d494Dd0Ac4a109F7706   
   - Account Key              : key is empty   
   - Default GasPrice         : 100000000000 wei   
   - Default Gas              : 200000 wei   
   - Default Value            : 0 wei   
   - Experimental Pragma list : []   
   - RPC connection timeout   : 100 Seconds   
   - Log file                 : gourmet.log
   
​GOURMET>

env.defaultValue.set

  • Set the defaultValue when sending a transaction

GOURMET> env.defaultValue.set (3000000);
Update DefaultValue: 3000000 wei
unit

​GOURMET> env
[*] Environment information:
   - Recipe Address           : http://localhost:9001   
   - Blockchain Node          : http://localhost:8545   
   - Account ID               : 0x8BAA3237cc980C0436Cd4d494Dd0Ac4a109F7706   
   - Account Key              : key is empty   
   - Default GasPrice         : 100000000000 wei   
   - Default Gas              : 200000 wei   
   - Default Value            : 3000000 wei   
   - Experimental Pragma list : []   
   - RPC connection timeout   : 100 Seconds   
   - Log file                 : gourmet.log

​GOURMET>

env.pragma.set

  • Set pragma to compile rol code

  • In solidity, pragma written in the code will be applied

  • When "" empty string is entered ad the argument, all pragma will be reset

GOURMET> env.pragma.set ("ABIEncoderV2");
Update Pragma: [ABIEncoderV2]
unit

​GOURMET> env.pragma.set ("smtchecker");
Update Pragma: [SMTChecker; ABIEncoderV2]
unit

​GOURMET> env.pragma.set ("");
Update Pragma: []
unit

​GOURMET>

env.rpcTimeout.set

  • Sets RPC timeout for interacting with blockchain node

  • The default timeout is 100 seconds

GOURMET> env.rpcTimeout.set (1000)
Update RPC timeout : 1000 Seconds
unit

​GOURMET> env
[*] Environment information:
   - Recipe Address           : http://localhost:9001   
   - Blockchain Node          : Node is empty   
   - Account ID               : ID is empty   
   - Account Key              : key is empty   
   - Default GasPrice         : default gas price   
   - Default Gas              : 6000000 wei   
   - Default Value            : 0 wei   
   - Experimental Pragma list : []   
   - RPC connection timeout   : 1000 Seconds   
   - Log file                 : gourmet.log

​GOURMET>

env.activeWallet.set

  • Generates transactions as the smart wallet on Gourmet

  • Can specify the name of the smart wallet instead of using EOA

GOURMET> let wallet = smartWallet.create ();

GOURMET> env.activeWallet.set (wallet);
Smart wallet is activated : 0x95d68cabb6df04f35e61c2e35058a8aa228f4dd2​

GOURMET> env
[*] Environment information:
   - Recipe Address           : http://localhost:9001   
   - Blockchain Node          : http://localhost:8546 (Ethereum mainnet)   
   - Account ID               : 0xd6fbf7e320be95062a2fd4d8348a87f5acdc92d6   
   - Account Key              : key is empty   
   - Default GasPrice         : default gas price   
   - Default Gas              : 6000000 wei   
   - Default Value            : 0 wei   
   - Experimental Pragma list : []   
   - RPC connection timeout   : 100 Seconds   
   - Log file                 : gourmet.log   
   - Active smart wallet      : 0x95d68cabb6df04f35e61c2e35058a8aa228f4dd2   
   - Caller Address           : No Caller registered.
   
​GOURMET>

env.caller.set

  • The caller contract is needed to use the smart wallet on Gourmet

  • Save the address of caller contract address on env to use on other smart wallets (this needs to be done only once)

GOURMET> env.caller.set (callerAddr);
Caller is registered : 0xcc6d49279b671ce69f3bf39e7e323227ac629fc2​

GOURMET> env
[*] Environment information:
   - Recipe Address           : http://localhost:9001   
   - Blockchain Node          : http://localhost:8546 (Ethereum mainnet)   
   - Account ID               : 0xd6fbf7e320be95062a2fd4d8348a87f5acdc92d6   
   - Account Key              : key is empty   
   - Default GasPrice         : default gas price   
   - Default Gas              : 6000000 wei   
   - Default Value            : 0 wei   
   - Experimental Pragma list : []   
   - RPC connection timeout   : 100 Seconds   
   - Log file                 : gourmet.log   
   - Active smart wallet      : 0x95d68cabb6df04f35e61c2e35058a8aa228f4dd2   
   - Caller Address           : 0xcc6d49279b671ce69f3bf39e7e323227ac629fc2​
   
GOURMET>

status

  • Returns the values stored on Gourmet

GOURMET> status

[*] Global Variable Status information:

 | compoundICTokenABI = /Prelude/ABI/Compound.ICToken.ABI.json
 | compoundICEtherABI = /Prelude/ABI/Compound.ICEther.ABI.json
 | compoundIComptrollerABI = /Prelude/ABI/Compound.IComptroller.ABI.json
 | compoundETHMainAddr = [(COMPTROLLER, 0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B), (CETHER, 0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5), (CUSDT, 0xf650C3d88D12dB855b8bf7D11Be6C55A4e07dCC9), (CUSDC, 0x39AA39c021dfbaE8faC545936693aC917d5E7563), (CUNI, 0x35A18000230DA775CAc24873d00Ff85BccdeD550), (CDAI, 0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643)]
 | compoundKovanAddr = [(COMPTROLLER, 0x5eae89dc1c671724a672ff0630122ee834098657), (CETHER, 0x41b5844f4680a8c38fbb695b7f9cfd1f64474a72), (CUSDT, 0x3f0a0ea2f86bae6362cf9799b523ba06647da018), (CUSDC, 0x4a92e71227d294f041bd82dd8f78591b75140d63), (CDAI, 0xf0d0eb522cfa50b716b3b1604c4f0fa6f04376ad)]
 | aaveV2ETHMainAddr = [(LENDINGPOOLADDRESSESPROVIDER, 0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5), (WETHGATEWAY, 0xcc9a0B7c43DC2a5F023Bb9b738E45B0Ef6B06E04), (AAVEPROTOCOLDATAPROVIDER, 0x057835Ad21a177dbdd3090bB1CAE03EaCF78Fc6d)]
 | aaveV2KovanAddr = [(LENDINGPOOLADDRESSESPROVIDER, 0x88757f2f99175387ab4c6a4b3067c77a695b0349), (WETHGATEWAY, 0xA61ca04DF33B72b235a8A28CfB535bb7A5271B70), (AAVEPROTOCOLDATAPROVIDER, 0x3c73A5E5785cAC854D468F727c606C07488a29D6)]
 | erc20TokenEthMainAddr = [(USDT, 0xdAC17F958D2ee523a2206206994597C13D831ec7), (USDC, 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48), (LINK, 0x514910771AF9Ca656af840dff83E8264EcF986CA), (DAI, 0x6B175474E89094C44Da98b954EedeAC495271d0F)]
 | erc20TokenKovanAddr = [(USDT, 0x38DaFB6F33aFa2276b3B5636d76769e849d99335), (USDC, 0x6329AA0D5EFd943cBdC8e31934361E5B8899D438), (LINK, 0x0a3061773FB691A6a0E988f77227a2F60A4BA68F), (DAI, 0x3Acb14b76496824513FaE001632071bffCBDb5Ce)]
 | erc20TokenBscMainAddr = [(USDT, 0x55d398326f99059ff775485246999027b3197955), (USDC, 0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d), (LINK, 0xF8A0BF9cF54Bb92F17374d9e9A321E6a111a51bD), (DAI, 0x1af3f329e8be154074d8769d1ffa4ee058b1dbc3)]
 | erc20TokenBscTestAddr = [(USDT, 0x177496ec3C7a38390ab477F211f409a405A57aF3), (USDC, 0xa43bB0d2B584360d683E5b2F38045f04CF8f90b2), (LINK, 0x4E6b5C26549De498e0105151dcBFbC345D239864), (DAI, 0x56e386606a975e9E947CfaFB79041957ED211fC1)]
 | uniswapV2ETHMainAddr = [(ROUTER02, 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D)]
 | uniswapV2KovanAddr = [(ROUTER02, 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D)]
 | uniswapV2BSCMainAddr = [(ROUTER02, 0x10ED43C718714eb63d5aA57B78B54704E256024E)]
 | uniswapV2BSCTestAddr = [(ROUTER02, 0xD99D1c33F9fC3444f8101754aBC46c52416550D1)]
 | walletABI = /Prelude/ABI/SmartWallet.ABI.json
 | bifiCallProxyABI = /Prelude/ABI/BifiCallProxy.ABI.json
 | bifiCoinHandlerProxyABI = /Prelude/ABI/BifiCoinHandlerProxy.ABI.json
 | bifiTokenHandlerProxyABI = /Prelude/ABI/BifiTokenHandlerProxy.ABI.json
 | bifiManagerABI = Prelude/ABI/BifiManager.ABI.json
 | bifiLiqdManagerABI = Prelude/ABI/BifiLiquidationManager.ABI.json
 | bifiEthMainAddr = [(CALLPROXY, 0x736a348bb7bdad117755c88bc4e1ab4ef07c5c50), (MANAGER, 0xc6c99a98bfe1ba7f9bd1dbaf0c9a74103e99af0d), (LIQDMANAGER, 0xFd514b33a361b82fE5D89070DB6917Cd4F73285D), (COINHANDLER, 0x13000c4a215efe7e414bb329b2f11c39bcf92d78), (USDTHANDLER, 0x808C3bA97268dbF9695b1EC10729E09c7e67A9E3), (USDCHANDLER, 0x128647690C7733593aA3Dd149EeBC5e256E79217), (LINKHANDLER, 0x25567603eb61A4A49f27e433652B5B8940D10682), (DAIHANDLER, 0xD76b7060F1B646fA14740Ff6Ac670a4f0A6fc5E3)]
 | bifiKovanAddr = [(CALLPROXY, 0xDCD4fdD2D5F1F6D2CAE43F2FA9E6194f4e398F3F), (MANAGER, 0x0AA87Fa3155bB771dCdd6473fCD57F5D68BB5cBc), (LIQDMANAGER, 0x88780DE6c34965781d25E8CdE1ac02407d8826F4), (COINHANDLER, 0xAdb6d77c19Bdf2D0538187787581a9C8C761714a), (USDTHANDLER, 0x9eD5AF6F51c8e2Aea90Ba4cBf9aF87d3D7C82b64), (USDCHANDLER, 0x087BE4F30028c914478a8ecD6395c3Be39262a82), (LINKHANDLER, 0x4EEF33499AaC237d04711c245db0aB0064922C51), (DAIHANDLER, 0x03dC1EAf896D4A9E74Cd8948E3fE591EE259e4B0)]
 | bifiBscMainAddr = [(CALLPROXY, 0xEA0C08aA00F1e890A618bE400Cb0e1aDa52926d5), (MANAGER, 0x1004460962095A3D4CeffE9ebb79505c3A70e7c8), (LIQDMANAGER, 0xd8855a0DFA5a4a44F9BA815D39D23D1DAd5Ac55D), (COINHANDLER, 0x170b6AA872166eC2F8515c2B855C34B6C7563c18), (USDTHANDLER, 0x2A29598cbc17BA112C8Fd0E07Fbf5402eF57E6b8), (USDCHANDLER, 0xBA9De5a8FD91408826616f2d6d7470A11E34c9F0), (DAIHANDLER, 0xB67C5433d234d656002f12664d15ab4b40666D9B), (ETHHANDLER, 0xf86d8218BCC15874f5D25c191FdDd43F2334c3EB)]
 | bifiBscTestAddr = [(CALLPROXY, 0x7bc012057BDCf34b468b3A6260aFe649bd3DF003), (MANAGER, 0x1004460962095A3D4CeffE9ebb79505c3A70e7c8), (LIQDMANAGER, 0xd8855a0DFA5a4a44F9BA815D39D23D1DAd5Ac55D), (COINHANDLER, 0x1114803a8E48289b284300243FDC7bddeE949917), (USDTHANDLER, 0xa41a583E43304760d123892A30567951495D57c0), (USDCHANDLER, 0x9aA67E233118689E5c890aBC7DA42d2378b82E19), (LINKHANDLER, 0x0e2CC4BEF7107Bda2aa754E8701C84408D4FD781), (DAIHANDLER, 0x0072278422ae8E452E9D9685C01fE94f11A1dbB4)]

print

  • Returns the stored values

GOURMET> let str = "hello";

GOURMET> let str2 = str + " " + "world";

GOURMET> print (str2);
"hello world"

runGanache

  • runGanache runs ganache-cli and creates Ganache object with Ganache instance

  • Enter the options that ganache-cli supports when running runGanache

  • The options that can be recived on Taster are as follows: Fork, Mnemonic, Hardfork, Port

  • You may set the field for options

  • If you don't set any options, the option runs default

GOURMET> runGanache (mnemonic: "brownie", hardfork: "istanbul", port: 8545)

​​GOURMET> let g = runGanache (mnemonic: "brownie", hardfork: "istanbul", port: 8545)

​GOURMET> ganacheInfo
[*] Ganache process information​
 | Process port       : 8545 
 | Fork provider      : 
 | Hardfork           : istanbul 
 | Mnemonic           : brownie 
 | Available Accounts :
  (0) "0x66ab6d9362d4f35596279692f0251db635165871" 
  (1) "0x33a4622b82d4c04a53e170c638b944ce27cffce3" 
  (2) "0x0063046686e46dc6f15918b61ae2b121458534a5" 
  (3) "0x21b42413ba931038f35e7a5224fadb065d297ba3" 
  (4) "0x46c0a5326e643e4f71d3149d50b48216e174ae84" 
  (5) "0x807c47a89f720fe4ee9b8343c286fc886f43191b" 
  (6) "0x844ec86426f076647a5362706a04570a5965473b" 
  (7) "0x23bb2bb6c340d4c91caa478edf6593fc5c4a6d4b" 
  (8) "0xa868bc7c1af08b8831795fac946025557369f69c" 
  (9) "0x1cee82eed89bd5be5bf2507a92a755dcf1d8e8dc"

genSolution (gen)

  • Create Solution object with the source code or procedure

When created with source code:

​GOURMET> let rol = gen ("..\rolSample\test.rol", "0.6.12")

​GOURMET> let sol = gen ("sample\sol\test.sol", "0.6.12")

​GOURMET> sInfo
[*] Solution information
 | Binded variable id : rol 
 | Solution name      : erc20TestSolution 
 | Solidity version   : 0.6.12 
 | Contract information
  | Binded variable id : sol 
  | Solution name      : test 
  | Solidity version   : 0.6.12 
  | Contract information
  
​GOURMET>
  • You may use with the following languages and version :

    • Solidity

    • ROL

    • "0.5.17"

    • "0.6.5"

    • "0.6.12"

    • "0.8.0"

To use another version of solidity, you have to do two things: 1) you must give the specific solidity version (as the second parameter) to Chainrunner by using gen cmd; and 2) the specific version of solidity compiler (solc) is placed to “/Gourmet/[TargetOS]/”.

For example, set solc0.7.0 file to the directory of the compiler and run gen ("someSolidity.sol", "0.7.0")

When created with procedure:

proc addSub(x, y) {
  let add = x + y;
  let sub = x - y;
  return (add, sub);
}

​let s = gen(  // 변환하는 프로시져의 이름  addSub,  // 타입을 명시할 프로시져 이름, 매개변수 타입, 결과 타입  [("addSub", ["uint256", "uint256"], ["uint256", "uint256"])]);
s.compile(optimize: true);
​let d = s.StubContract();
d.stubFunction(10, 20);​
  • The solution name created with procedure is StubContract and the function is stubFunction

  • The parameters of the procedure and the return value type must be specified. If there is no paramter or return value, it can be omitted.

proc dumb() {}
let s = gen(dumb);
  • The procedures that require off-chain processes, such as env-based commands, reg, or gen, cannot be used.

  • The procedure can call function as env.account using delegateCall.

// 아래 호출은 생성되는 컨트렉트가 아닌, env.account의 명의로 실행됩니다.
let ok = weth.transfer.delegateCall(to);
if (!ok) { ... }
  • In procedures that creates the solution, you can avoid type ambiguity of variables by specifying type information.

    • "hello": has type ambiguity

    • 10: has type ambiguity

// `0`은 부호와 크기가 다양할 수 있는 수를 표현하기 때문에, 명시 필요
let sum = 0:int;

// 한 번 타입을 안 이후에는, 명시할 필요 없음
let sum = sum + 1;
  • In procedures that creates the solution, deployment calls can only be made in variable delcaration. If multiple values are returned, they must be closed immediately after it is returned.

let x = d.returnTwoValues(); // invalid
let (x, y) = d.returnTwoValues(); // good
  • May deploy the compiled contract

  • Cannot use the deployed deployment. Declaration for variable is made, but the feature for re-using the variable is currently not implemented.

let vaultSolution = gen("vault.sol", "0.6.12");
vaultSolution.compile(optimize: true);
​proc deploy() {
  let _ = vaultSolution.Vault("hello":string);
}
​​let deploySolution = gen(deploy);
deploySolution.compile(optimize: true);
​let deployDeployment = deploySolution.StubContract();
deployDeployment.stubFunction();
  • To change the call of the procedure, the type of the procedure that is used must be specified

proc main() {
  proc awesomeProc(_) {
    proc add(a, b) {
      return a + b;
    }
    proc mul(a, b) {
      return a * b;
    }
    
    proc addMul(a, b, c) {
      let ret = add(a, b);
      let ret = mul(ret, c);
      return ret;
    }​
    
    let ret = addMul(10:uint256, 20:uint256, 30:uint256);
    return ret;
  }
  ​let s = gen(awesomeProc, [    ("awesomeProc", ["bool"], ["uint256"]),    ("awesomeProc.add", ["uint256", "uint256"], ["uint256"]),    ("awesomeProc.mul", ["uint256", "uint256"], ["uint256"]),    ("awesomeProc.addMul", ["uint256", "uint256", "uint256"], ["uint256"])  ]);​  
  print(s.getCodes());
  s.compile();
}

​main();​

regContract (reg)

  • Create a Deployment type object by receiving the deployed contract address and ABI

  • If the contract is deployed through Gourmet, you can do address regContract

  • It is recommended that blockNumber is entered (when known)

    • Range-based event search is not allowed if blockNumber is not entered

    • (txHash-based search is allowed)

// If you don't know the deployed Block Number
GOURMET> let ctr_bfc = reg ("0x0c7D5ae016f806603CB1782bEa29AC69471CAb9c", "erc20abi.json")

​// If you know the deployed Block Number
GOURMET> let ctr_bfc = reg ("0x0c7D5ae016f806603CB1782bEa29AC69471CAb9c", "erc20abi.json", 1232134)

// Only contracts distributed by Gourmet can perform regContract with only address.
GOURMET> wallet.Wallet ();
'Wallet' was deployed.
'Wallet' deploy fee: 22549820000000000.
Deployment <0x0a24d3e827797623e198c41859f6c306a0eadb09, Some(12350002)>

​GOURMET> let w = reg ("0x0a24d3e827797623e198c41859f6c306a0eadb09")

​GOURMET> dInfo[*] 
Deployment information
 | Binded variable id    : w
 | Deployed address      : 0x0a24d3e827797623e198c41859f6c306a0eadb09 
 | Deployed block number : Some(12350002) 
 | Contract description
    | Contract name : unknown
       | Function information
         | addAuthority (address src, bytes4 sig) return ()
         | cache () return (address )     
         | execute (address _target, bytes _data) return (bytes )     
         | execute (bytes _code, bytes _data) return (bytes response)     
         | owner () return (address )     
         | removeAuthority (address src) return ()     
         | setCache (address _cacheAddr) return (bool )     
         | transferEther (address to, uint256 amount) return ()     
         | transferOwnership (address newOwner) return ()

solutionInfo (sInfo)

  • Returns the information for all saved solutions

GOURMET> sinfo
[*] Solution information
 | Binded variable id : sln_yeh 
 | Solution name      : SolutionERC20 
 | Solidity version   : 0.6.12 
 | Contract information
    | Contract name : ERC20
       | Contract name : ContractERC20
          | Contract description
               | Contract name : ContractERC20       
               | Function information
                   | constructor (string name,string symbol,uint256 amount) return ()       
                   | name () return (string)       
                   | symbol () return (string)       
                   | decimals () return (uint8)       
                   | totalSupply () return (uint256)       
                   | balanceOf (address account) return (uint256)       
                   | transfer (address recipient,uint256 amount) return (bool)       
                   | allowance (address owner,address spender) return (uint256)       
                   | approve (address spender,uint256 amount) return (bool)       
                   | transferFrom (address sender,address recipient,uint256 amount) return (bool)       
                   | increaseAllowance (address spender,uint256 addedValue) return (bool)       
                   | decreaseAllowance (address spender,uint256 subtractedValue) return (bool)       
                   | _transfer (address sender,address recipient,uint256 amount) return ()       
                   | _mint (address account,uint256 amount) return ()       
                   | _burn (address account,uint256 amount) return ()       
                   | _approve (address owner,address spender,uint256 amount) return ()       
                   | _setupDecimals (uint8 decimals_) return ()       
                   | _beforeTokenTransfer (address from,address to,uint256 amount) return ()​

deploymentInfo (dInfo)

  • Returns the information for all saved deployment (contract)

GOURMET> dinfo
[*] Deployment information
 | Binded variable id    : ctr_yeh 
 | Blockchaing address   : http://127.0.0.1:8545 
 | Deployed address      : 0xea07f79d098e0b4004d29ed66c2420e8046fed13 
 | Deployed block number : Some(94) 
 | Contract description   
 | Contract name : ContractERC20   
 | Function information
      | constructor (string name,string symbol,uint256 amount) return ()     
      | name () return (string)     
      | symbol () return (string)     
      | decimals () return (uint8)     
      | totalSupply () return (uint256)     
      | balanceOf (address account) return (uint256)     
      | transfer (address recipient,uint256 amount) return (bool)     
      | allowance (address owner,address spender) return (uint256)     
      | approve (address spender,uint256 amount) return (bool)     
      | transferFrom (address sender,address recipient,uint256 amount) return (bool)     
      | increaseAllowance (address spender,uint256 addedValue) return (bool)     
      | decreaseAllowance (address spender,uint256 subtractedValue) return (bool)     
      | _transfer (address sender,address recipient,uint256 amount) return ()     
      | _mint (address account,uint256 amount) return ()     
      | _burn (address account,uint256 amount) return ()     
      | _approve (address owner,address spender,uint256 amount) return ()     
      | _setupDecimals (uint8 decimals_) return ()     
      | _beforeTokenTransfer (address from,address to,uint256 amount) return () 
 | Binded variable id    : ctr_bfc 
      | Blockchaing address   : http://127.0.0.1:8545 
      | Deployed address      : 0x0c7D5ae016f806603CB1782bEa29AC69471CAb9c 
      | Deployed block number :
      | Contract description
         | Contract name : unknown
            | Function information
                 | name () return (string)
                 | approve (address _spender,uint256 _value) return (bool)
                 | totalSupply () return (uint256)     
                 | transferFrom (address _from,address _to,uint256 _value) return (bool)     
                 | decimals () return (uint8)     
                 | balanceOf (address _owner) return (uint256)     
                 | symbol () return (string)     
                 | transfer (address _to,uint256 _value) return (bool)     
                 | allowance (address _owner,address _spender) return (uint256)

ganacheInfo (gInfo)

  • Returns all running ganache processes

GOURMET> gInfo
[*] Ganache process information​
 | Process port       : 8546
 | Fork provider      :
 | Hardfork           : 
 | Mnemonic           : brownie 
 | Available Accounts : (0) "0x66ab6d9362d4f35596279692f0251db635165871" (1) "0x33a4622b82d4c04a53e170c638b944ce27cffce3" (2) "0x0063046686e46dc6f15918b61ae2b121458534a5" (3) "0x21b42413ba931038f35e7a5224fadb065d297ba3" (4) "0x46c0a5326e643e4f71d3149d50b48216e174ae84" (5) "0x807c47a89f720fe4ee9b8343c286fc886f43191b" (6) "0x844ec86426f076647a5362706a04570a5965473b" (7) "0x23bb2bb6c340d4c91caa478edf6593fc5c4a6d4b" (8) "0xa868bc7c1af08b8831795fac946025557369f69c" (9) "0x1cee82eed89bd5be5bf2507a92a755dcf1d8e8dc"​ | Process port       : 9008 | Fork provider      : | Hardfork           : | Mnemonic           : | Available Accounts : (0) "0x52f96b50c7d12eeec07e91eaa00ca1180f59d6a6" (1) "0x25b759bb6bdc52804981175a4c09b39ccb96d7f5" (2) "0x8baec309919ef176551c6f874d44e0e0ab6aeb13" (3) "0x49a3d9f10ffe30b541bb23f19c827d5c7136b63b" (4) "0x5f89ed168a5c2c1742ce338c8fef4f898ce9e172" (5) "0xcb994ea1731bb301e90f032a496b225a45b5f76e" (6) "0xd16209d9946da1fcdb042e530575a50ffbc5b733" (7) "0x3ffb2fd7f4c1811eb3fd1d06b312cd8cd3c59371" (8) "0x530d87d9c3e65bb550b07e99be56cf90f73da797" (9) "0x64c80075a3df8e2fb4090ff994a7759b6b17b3cd"

procedureInfo (pInfo)

  • Returns the information on procedures currently defined in Gourmet

  • Once entering procedureName that follows cmd, it returns the information of the specified procedure

GOURMET> procedureInfo
[*] Procedure information
 | aaveV2Ether ()                                            
 | bifi ()                                                                                                                                                     | compound ()                                                   
 | erc20 ()                                      
 | test ()                                                                 
 | uniswapV2 ()                                                           
 | aaveV2Ether.aaveProtocolDataProvider ()            
 | aaveV2Ether.aaveProtocolDataProvider.getAddress ()
  ...​

GOURMET> pinfo uni
[*] Procedure information 
 | uniswapV2 () 
 | uniswapV2.router02 () 
 | uniswapV2.router02.addLiquidity (tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin, to, deadline)
  ...

Transfer

  • Transfer Ether to the specified address

GOURMET> let recipient = "0x379c0ac6c6091195921b410ed37519076ec68340";

GOURMET> let amount = 1000000000000000000;

GOURMET> transfer (recipient, amount);

assert

  • Provides the assert feature for executing each cmd

  • Ends the scenario if it fails to assert when executing Gourmet with CliDriver

GOURMET> let old_a = ctr_yeh.balanceOf (sender)

​GOURMET> let old_b = ctr_yeh.balanceOf (receiver)

​GOURMET> ctr_yeh.transfer (receiver, 33)
'transfer(address,uint256)' send transaction fee : 34154.
"0x424ad5973748fdad630636f056382305e847873ad5c6fd70d7bae4fb592490d5"

​GOURMET> let new_a = ctr_yeh.balanceOf (sender)

​GOURMET> let new_b = ctr_yeh.balanceOf (receiver)

​GOURMET> assert (old_a + old_b == new_a + new_b)
Assert : True

​GOURMET> assert (false, "die")
Assert : False
Error : Assertion error : die​

this.getAddress

  • Returns the current location of the procedure when the procedure is genSolution()and deployed

  • Returns "0x0":address when running on Gourmet

proc p() {
  let a = this.getAddress()
}

​p(); // a = "0x0":address

​let s = gen(p, [], ["address"]);
s.compile();
​let d = s.StubContract();
d.stubFunction(); // a = d.getAddress()

addBlocks

  • Increases the block number

  • Creates a block with a dummy transaction

    • Runs only in private blockchains such as ganache

GOURMET> addBlocks (2);
2 block(s) was added.
unit

​GOURMET>

getAccount

  • Retrieves the account information set on env

GOURMET> getAccount ();
("0x66aB6D9362d4F35596279692F0251Db635165871", "0xbbfbee4961061d506ffbb11dfea64eba16355cbf1d9c29613126ba7fec0aed5d")

​GOURMET> let (id, key) = getAccount ();​

GOURMET> let account = getAccount ();​

GOURMET> print(id);
"0x66aB6D9362d4F35596279692F0251Db635165871"

​GOURMET> print(key);
"0xbbfbee4961061d506ffbb11dfea64eba16355cbf1d9c29613126ba7fec0aed5d"

​GOURMET> print(account);
("0x66aB6D9362d4F35596279692F0251Db635165871", "0xbbfbee4961061d506ffbb11dfea64eba16355cbf1d9c29613126ba7fec0aed5d")

​GOURMET>

getBlockNumber

  • Returns the block number of the node

GOURMET> getBlockNumber ();
9

GOURMET> let blockNumber = getBlockNumber ();

GOURMET> print(blockNumber);
9

getBalance

  • Returns the account balance of a specific target

  • If the target is not set, returns the account balance set in Gourmet

GOURMET> getBalance ();
99999016800000000000

​GOURMET> let ownerBalance = getBalance ();​

GOURMET> assert (ownerBalance == getBalance ());
Assert(Equal) : True

​​GOURMET> deploy 1 2 {Gas = 1000000} ("bfc", "BFC", 10000);
'testERC20' Contract was deployed.
"0x5047ee70dffe861aa06dfae9325dbfe35cd9f49d"

​GOURMET> assert (ownerBalance == getBalance ());
Assert(Equal) : False

​​GOURMET> getBalance ();

99980533600000000000

​GOURMET> let user3 = "0xF4d23ddd87FFC0423740667A609fF7f67effad42";​

GOURMET> getBalance (user3);100000000000000000000

​GOURMET> getBalance ("0xF4d23ddd87FFC0423740667A609fF7f67effad42");
100000000000000000000

​GOURMET> getBalance ("F4d23ddd87FFC0423740667A609fF7f67effad42");
100000000000000000000

​GOURMET> getBalance ("abc");
0

​GOURMET> getBalance ("abcdefgh");
Error : invalid address

​GOURMET> getBalance (abcdefgh);
Error : Invalid Value

​GOURMET>

getBalances

  • Returns all of the balances supported on Gourmet of the specific target account

  • If the target is not set, returns the account balance set in Gourmet

  • The example below shows the fork test result of ether mainnet and bsc testnet

C:\DEV\Gourmet.2>src\FrontEnd\Gourmet-REPL\bin\Debug\netcoreapp5.0\gourmet.exe
Hello World from Gourmet!
GOURMET> env.blockchain.set ("http://localhost:8545");
Update Blockchain Node: http://localhost:8545 (Ethereum mainnet))

GOURMET> let account1 = "0x66aB6D9362d4F35596279692F0251Db635165871";

GOURMET> let account2 = "0x33A4622B82D4c04a53e170c638B944ce27cffce3";

GOURMET> env.account.set (account2);
Update Account:
  Account ID : 0x33A4622B82D4c04a53e170c638B944ce27cffce3

GOURMET>
GOURMET> getBalances ();
[(ETH, 57193626064746234669), (USDT, 10000000), (USDC, 0), (LINK, 150000000000000000000), (DAI, 1000000000000000000), (BFC, 10000000000000000000), (BIFI, 1000000000000000000)]

GOURMET> getBalances (account1);
[(ETH, 100000000000000000000), (USDT, 0), (USDC, 0), (LINK, 0), (DAI, 0), (BFC, 0), (BIFI, 0)]

GOURMET> let ganache = runGanache (fork: "https://data-seed-prebsc-1-s2.binance.org:8545@6692210", mnemonic: "brownie", hardfork: "istanbul");

GOURMET> env.blockchain.set (ganache);
Update Blockchain Node: http://localhost:8546 (BSC testnet))

GOURMET> let accounts = ganache.getAccounts();

GOURMET> env.account.set (accounts[0]);
Update Account:
  Account ID : 0x66ab6d9362d4f35596279692f0251db635165871

GOURMET> let account2 = accounts[1];

GOURMET> getBalances ();
[(BSC, 100000000000000000000), (USDT, 0), (USDC, 0), (LINK, 0), (DAI, 0)]

GOURMET>

insert

  • Inserts a scenario written in an external (another) file into the current scenario

  • Enter the relative path or the absolute path of the file you want to insert

  • Be careful not be make circular references between the files that you want to insert

  • Use as keyword to assign symbols. Can be used as procedure

/// Test scenario file...
insert ".\ERC20Test3.test" as ERC20Test3...

run

  • REPL runs the entire file (scenario) for taster

  • Details of the gas fee are shown when the scenario ends.

  • Same as running a scenario with Gourmet’s CliDriver

GOURMET> run ERC20Test2.test
Deleted Internal context.
Deleted External(ExcutionEngine) context.
Update Account: 0xcdF66c46F4C2ca27fdd987fE07e6734Bf1f9C304
Update Blockchain Node: http://localhost:8545
[*] Environment information:
- Recipe Address          : http://localhost:9001
- Blockchain Node         : http://localhost:8545
- Account Address         : 0xcdF66c46F4C2ca27fdd987fE07e6734Bf1f9C304
- Log file                : gourmet.log
New contract has been added.
Solution was compiled.
'testERC20' Contract was deployed.
"0x342446d5a34d21b42a79a961d838d423b5525dab"
"bfc"
"BFC"
1000
10000
True
95050
Update Account: 0xD5870c41A4d5915D386DdBAbc00A6D15DB6D0724
True
4010
​Scenario evaluate complete.

​GOURMET>

sleep

  • Temporarily suspends the thread for the specified time

  • The unit of factor is seconds

GOURMET> let _ = sleep (2);

​GOURMET>

Comment

  • Supports single-line annotations and multi-line annotations

  • Does not work in Gourmet REPL

// This is a single-line comment.
​/*This is amulti-line comment.*/

Keyword List

  • List of Taster keywords

  • The characters below are used as keywords. Cannot be used as variables, function names, etc.

[
    "true", TRUE
    "false", FALSE
    "call", CALL
    "delegateCall", DELEGATECALL
    "genSolution", GENSOLUTION
    "gen", GENSOLUTION
    "regContract", REGCONTRACT
    "reg", REGCONTRACT
    "assert", ASSERT
    "let", LET
    "clear", CLEAR
    "all", ALL
    "gasFeeInfo", GASFEEINFO
    "internal", INTERNAL
    "external", EXTERNAL
    "send", SEND
    "compile", COMPILE
    "Value", VALUE
    "Gas", GAS
    "addBlocks", ADDBLOCKS
    "string", TYSTRING
    "address", TYADDRESS
    "flashloanObject", FLASHLOANOBJECT
    "runGanache", RUNGANACHE
    "proc", PROC
    "insert", INSERT
    "as", AS
    "if", IF
    "else", ELSE
    "return", RETURN
    "atomic", ATOMIC
    "for", FOR
    "in", IN
    "ether", ETHER
    "wei", WEI
    "gwei", GWEI
  ] |> Map.ofList

Last updated