Skip to content

Commit

Permalink
Merge branch 'topic/hardfork-v4' into feature/composable-transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
kroggen committed Jul 9, 2024
2 parents d54ca44 + fedc0c3 commit f406be7
Show file tree
Hide file tree
Showing 79 changed files with 4,494 additions and 1,960 deletions.
2 changes: 1 addition & 1 deletion aergo-protobuf
59 changes: 59 additions & 0 deletions blacklist/blacklist.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package blacklist

import (
"github.com/aergoio/aergo/v2/types"
"github.com/aergoio/aergo/v2/internal/common"
"github.com/aergoio/aergo/v2/internal/enc/hex"
)

type Blacklist struct {
sourcelist []string // account address (b58 encoded like Am...) or id (32 bytes in hex = 64 bytes)
blocked map[string]bool // all above converted to account id (32 bytes)
}

var globalBlacklist *Blacklist

// Initialize sets up the blacklist with the given addresses.
// This function should be called only once at the start.
func Initialize(addresses []string) {
conf := &Blacklist{}
conf.sourcelist = make([]string, len(addresses))
copy(conf.sourcelist, addresses)
conf.blocked = make(map[string]bool)
for _, v := range addresses {
key, err := toKey(v)
if err == nil {
conf.blocked[key] = true
} else {
// Handle invalid address, log or take other actions as needed
}
}
globalBlacklist = conf
}

func Check(address string) bool {
if globalBlacklist == nil {
return false
}
key, err := toKey(address)
if err != nil {
return false
}
return globalBlacklist.blocked[key]
}

func toKey(address string) (string, error) {
var key []byte
var err error
if len(address) == 64 {
key, err = hex.Decode(address)
} else {
var addr []byte
addr, err = types.DecodeAddress(address)
if err != nil {
return "", err
}
key = common.Hasher(addr)
}
return string(key), err
}
62 changes: 30 additions & 32 deletions cmd/aergocli/cmd/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,17 @@ func init() {
contractCmd.PersistentFlags().Uint64VarP(&gas, "gaslimit", "g", 0, "Gas limit")

deployCmd := &cobra.Command{
Use: `deploy [flags] --payload 'payload string' <creatorAddress> [args]
aergocli contract deploy [flags] <creatorAddress> <bcfile> <abifile> [args]
Use: `deploy [flags] <creatorAddress> <path-to-lua-file> [args]
aergocli contract deploy [flags] <creatorAddress> --payload 'payload string' [args]
You can pass constructor arguments by passing a JSON string as the optional final parameter, e.g. "[1, 2, 3]".`,
Short: "Deploy a compiled contract to the server",
Args: nArgs([]int{1, 2, 3, 4}),
You can pass arguments to the constructor() function by passing a JSON string as the optional final parameter, e.g. '[1, "test"]'`,
Short: "Deploy a contract to the server",
Args: nArgs([]int{1, 2, 3}),
RunE: runDeployCmd,
DisableFlagsInUseLine: true,
}
deployCmd.PersistentFlags().Uint64Var(&nonce, "nonce", 0, "manually set a nonce (default: set nonce automatically)")
deployCmd.PersistentFlags().StringVar(&data, "payload", "", "result of compiling a contract")
deployCmd.PersistentFlags().StringVar(&data, "payload", "", "result of compiling a contract with aergoluac")
deployCmd.PersistentFlags().StringVar(&amount, "amount", "0", "amount of token to send with deployment, in aer")
deployCmd.PersistentFlags().StringVarP(&contractID, "redeploy", "r", "", "redeploy the contract")
deployCmd.Flags().StringVar(&pw, "password", "", "password (optional, will be asked on the terminal if not given)")
Expand Down Expand Up @@ -145,20 +145,6 @@ func init() {
rootCmd.AddCommand(contractCmd)
}

func isHexString(s string) bool {
// check is the input has even number of characters
if len(s)%2 != 0 {
return false
}
// check if the input contains only hex characters
for _, c := range s {
if !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {
return false
}
}
return true
}

func runDeployCmd(cmd *cobra.Command, args []string) error {
var err error
var code []byte
Expand All @@ -179,31 +165,39 @@ func runDeployCmd(cmd *cobra.Command, args []string) error {
nonce = state.GetNonce() + 1
}

chainInfo, err := client.GetChainInfo(context.Background(), &types.Empty{})
if err != nil {
return fmt.Errorf("could not retrieve chain info: %v", err.Error())
}

var payload []byte
if len(data) == 0 {
if len(args) < 3 {
if chainInfo.Id.Version < 4 {
cmd.SilenceUsage = false
return errors.New("for old hardforks use aergoluac and --payload method instead")
}
if len(args) < 2 {
cmd.SilenceUsage = false
return errors.New("not enough arguments")
}
code, err = os.ReadFile(args[1])
if err != nil {
return fmt.Errorf("failed to read code file: %v", err.Error())
}
var abi []byte
abi, err = os.ReadFile(args[2])
if err != nil {
return fmt.Errorf("failed to read abi file: %v", err.Error())
}
if len(args) == 4 {
if len(args) == 3 {
var ci types.CallInfo
err = json.Unmarshal([]byte(args[3]), &ci.Args)
err = json.Unmarshal([]byte(args[2]), &ci.Args)
if err != nil {
return fmt.Errorf("failed to parse JSON: %v", err.Error())
return fmt.Errorf("failed to parse arguments (JSON): %v", err.Error())
}
deployArgs = []byte(args[3])
deployArgs = []byte(args[2])
}
payload = luac.NewLuaCodePayload(luac.NewLuaCode(code, abi), deployArgs)
payload = luac.NewLuaCodePayload(luac.LuaCode(code), deployArgs)
} else {
if chainInfo.Id.Version >= 4 {
cmd.SilenceUsage = false
return errors.New("this chain only accepts deploy in plain source code\nuse the other method instead")
}
if len(args) == 2 {
var ci types.CallInfo
err = json.Unmarshal([]byte(args[1]), &ci.Args)
Expand All @@ -213,7 +207,11 @@ func runDeployCmd(cmd *cobra.Command, args []string) error {
deployArgs = []byte(args[1])
}
// check if the data is in hex format
if isHexString(data) {
if hex.IsHexString(data) {
if deployArgs != nil {
cmd.SilenceUsage = false
return errors.New("the call arguments are expected to be already on the hex data")
}
// the data is expected to be copied from aergoscan view of
// the transaction that deployed the contract
payload, err = hex.Decode(data)
Expand Down
14 changes: 12 additions & 2 deletions cmd/aergoluac/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ var (
rootCmd *cobra.Command
abiFile string
payload bool
decode bool
version bool
)

var githash = "No git hash provided"

func init() {
rootCmd = &cobra.Command{
Use: "aergoluac --payload srcfile\n aergoluac --abi abifile srcfile bcfile",
Use: "aergoluac --payload srcfile\n aergoluac srcfile bcfile\n aergoluac --abi abifile srcfile bcfile\n aergoluac --decode payloadfile",
Short: "Compile a lua contract",
Long: "Compile a lua contract. This command makes a bytecode file and a ABI file or prints a payload data.",
RunE: func(cmd *cobra.Command, args []string) error {
Expand All @@ -34,7 +35,14 @@ func init() {
cmd.Printf("Aergoluac %s\n", githash)
return nil
}
if payload {

if decode {
if len(args) == 0 {
err = util.DecodeFromStdin()
} else {
err = util.DecodeFromFile(args[0])
}
} else if payload {
if len(args) == 0 {
err = util.DumpFromStdin()
} else {
Expand All @@ -46,11 +54,13 @@ func init() {
}
err = util.CompileFromFile(args[0], args[1], abiFile)
}

return err
},
}
rootCmd.PersistentFlags().StringVarP(&abiFile, "abi", "a", "", "abi filename")
rootCmd.PersistentFlags().BoolVar(&payload, "payload", false, "print the compilation result consisting of bytecode and abi")
rootCmd.PersistentFlags().BoolVar(&decode, "decode", false, "extract raw bytecode and abi from payload (hex or base58)")
rootCmd.PersistentFlags().BoolVar(&version, "version", false, "print the version number of aergoluac")
}

Expand Down
93 changes: 93 additions & 0 deletions cmd/aergoluac/util/luac_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"runtime"
"unsafe"

"github.com/aergoio/aergo/v2/internal/enc/hex"
"github.com/aergoio/aergo/v2/internal/enc/base58"
"github.com/aergoio/aergo/v2/cmd/aergoluac/encoding"
)

Expand Down Expand Up @@ -130,6 +132,97 @@ func dumpToBytes(L *C.lua_State) LuaCode {
return NewLuaCode(C.GoBytes(unsafe.Pointer(c), C.int(lc)), C.GoBytes(unsafe.Pointer(a), C.int(la)))
}

func Decode(srcFileName string, payload string) error {
var decoded []byte
var err error

// check if the payload is in hex format
if hex.IsHexString(payload) {
// the data is expected to be copied from aergoscan view of
// the transaction that deployed the contract
decoded, err = hex.Decode(payload)
} else {
// the data is the output of aergoluac
decoded, err = encoding.DecodeCode(payload)
if err != nil {
// the data is extracted from JSON transaction from aergocli
decoded, err = base58.Decode(payload)
}
}
if err != nil {
return fmt.Errorf("failed to decode payload 1: %v", err.Error())
}

data := LuaCodePayload(decoded)
_, err = data.IsValidFormat()
if err != nil {
return fmt.Errorf("failed to decode payload 2: %v", err.Error())
}

contract := data.Code()
if !contract.IsValidFormat() {
// the data is the output of aergoluac, so it does not contain deploy arguments
contract = LuaCode(decoded)
data = NewLuaCodePayload(contract, []byte{})
}

err = os.WriteFile(srcFileName + "-bytecode", contract.ByteCode(), 0644);
if err != nil {
return fmt.Errorf("failed to write bytecode file: %v", err.Error())
}

err = os.WriteFile(srcFileName + "-abi", contract.ABI(), 0644);
if err != nil {
return fmt.Errorf("failed to write ABI file: %v", err.Error())
}

var deployArgs []byte
if data.HasArgs() {
deployArgs = data.Args()
}
err = os.WriteFile(srcFileName + "-deploy-arguments", deployArgs, 0644);
if err != nil {
return fmt.Errorf("failed to write deploy-arguments file: %v", err.Error())
}

fmt.Println("done.")
return nil
}

func DecodeFromFile(srcFileName string) error {
payload, err := os.ReadFile(srcFileName)
if err != nil {
return fmt.Errorf("failed to read payload file: %v", err.Error())
}
return Decode(srcFileName, string(payload))
}

func DecodeFromStdin() error {
fi, err := os.Stdin.Stat()
if err != nil {
return err
}
var buf []byte
if (fi.Mode() & os.ModeCharDevice) == 0 {
buf, err = ioutil.ReadAll(os.Stdin)
if err != nil {
return err
}
} else {
var bBuf bytes.Buffer
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
bBuf.WriteString(scanner.Text() + "\n")
}
if err = scanner.Err(); err != nil {
return err
}
buf = bBuf.Bytes()
}
return Decode("contract", string(buf))
}


type LuaCode []byte

const byteCodeLenLen = 4
Expand Down
49 changes: 49 additions & 0 deletions cmd/brick/context/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,55 @@ func ParseFirstWord(input string) (string, string) {
return strings.ToLower(splitedStr[0]), strings.Join(splitedStr[1:], " ")
}

func ParseDecimalAmount(str string, digits int) string {

// if there is no 'aergo' unit, just return the amount str
if !strings.HasSuffix(strings.ToLower(str), "aergo") {
return str
}

// remove the 'aergo' unit
str = str[:len(str)-5]
// trim trailing spaces
str = strings.TrimRight(str, " ")

// get the position of the decimal point
idx := strings.Index(str, ".")

// if not found, just add the leading zeros
if idx == -1 {
return str + strings.Repeat("0", digits)
}

// Get the integer and decimal parts
p1 := str[0:idx]
p2 := str[idx+1:]

// Check for another decimal point
if strings.Index(p2, ".") != -1 {
return "error"
}

// Compute the amount of zero digits to add
to_add := digits - len(p2)
if to_add > 0 {
p2 = p2 + strings.Repeat("0", to_add)
} else if to_add < 0 {
// Do not truncate decimal amounts
return "error"
}

// Join the integer and decimal parts
str = p1 + p2

// Remove leading zeros
str = strings.TrimLeft(str, "0")
if str == "" {
str = "0"
}
return str
}

type Chunk struct {
Accent bool
Text string
Expand Down
3 changes: 2 additions & 1 deletion cmd/brick/exec/callContract.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ func (c *callContract) parse(args string) (string, *big.Int, string, string, str
return "", nil, "", "", "", "", "", fmt.Errorf("need at least 4 arguments. usage: %s", c.Usage())
}

amount, success := new(big.Int).SetString(splitArgs[1].Text, 10)
amountStr := context.ParseDecimalAmount(splitArgs[1].Text, 18)
amount, success := new(big.Int).SetString(amountStr, 10)
if success == false {
return "", nil, "", "", "", "", "", fmt.Errorf("fail to parse number %s", splitArgs[1].Text)
}
Expand Down
Loading

0 comments on commit f406be7

Please sign in to comment.