Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deploy contracts as plain code #266

Merged
merged 12 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 29 additions & 17 deletions cmd/aergocli/cmd/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,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 @@ -164,31 +164,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 @@ -199,6 +207,10 @@ func runDeployCmd(cmd *cobra.Command, args []string) error {
}
// check if the data is in hex format
if 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
23 changes: 19 additions & 4 deletions contract/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -891,17 +891,32 @@ func setRandomSeed(ctx *vmContext) {
ctx.seed = rand.New(randSrc)
}

func setContract(contractState *statedb.ContractState, contractAddress, payload []byte) ([]byte, []byte, error) {
func setContract(contractState *statedb.ContractState, contractAddress, payload []byte, ctx *vmContext) ([]byte, []byte, error) {
codePayload := luacUtil.LuaCodePayload(payload)
if _, err := codePayload.IsValidFormat(); err != nil {
ctrLgr.Warn().Err(err).Str("contract", types.EncodeAddress(contractAddress)).Msg("deploy")
return nil, nil, err
}
code := codePayload.Code()

// if hardfork version 4
if ctx.blockInfo.ForkVersion >= 4 {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this part would insure that code running in blocks with forkversion < 4 to run as previously @hayarobi

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The contract execution code was not modified. It remains exactly the same

// the payload must be lua code. compile it to bytecode
var err error
code, err = Compile(string(code), nil)
if err != nil {
ctrLgr.Warn().Err(err).Str("contract", types.EncodeAddress(contractAddress)).Msg("deploy")
return nil, nil, err
}
//} else {
// on previous hardfork versions the payload is bytecode
}

err := contractState.SetCode(code.Bytes())
if err != nil {
return nil, nil, err
}

contract := getContract(contractState, nil)
if contract == nil {
err = fmt.Errorf("cannot deploy contract %s", types.EncodeAddress(contractAddress))
Expand All @@ -917,11 +932,11 @@ func setContract(contractState *statedb.ContractState, contractAddress, payload

func Create(
contractState *statedb.ContractState,
code, contractAddress []byte,
payload, contractAddress []byte,
ctx *vmContext,
) (string, []*types.Event, *big.Int, error) {

if len(code) == 0 {
if len(payload) == 0 {
return "", nil, ctx.usedFee(), errors.New("contract code is required")
}

Expand All @@ -930,7 +945,7 @@ func Create(
}

// save the contract code
contract, args, err := setContract(contractState, contractAddress, code)
contract, args, err := setContract(contractState, contractAddress, payload, ctx)
if err != nil {
return "", nil, ctx.usedFee(), err
}
Expand Down
23 changes: 23 additions & 0 deletions contract/vm_dummy/vm_dummy.go
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,19 @@ func NewLuaTxDeploy(sender, recipient string, amount uint64, code string) *luaTx
return NewLuaTxDeployBig(sender, recipient, types.NewAmount(amount, types.Aer), code)
}

func NewLuaTxDeployBig(sender, recipient string, amount *big.Int, code string) *luaTxDeploy {
return &luaTxDeploy{
luaTxContractCommon: luaTxContractCommon{
_sender: contract.StrHash(sender),
_recipient: contract.StrHash(recipient),
_payload: util.NewLuaCodePayload([]byte(code), nil),
_amount: amount,
txId: newTxId(),
},
cErr: nil,
}
}

/*
func contract.StrHash(d string) []byte {
// using real address
Expand Down Expand Up @@ -534,6 +547,16 @@ func (l *luaTxDeploy) run(execCtx context.Context, bs *state.BlockState, bc *Dum
if l.cErr != nil {
return l.cErr
}
if bc.HardforkVersion < 4 {
// compile the plain code to bytecode
payload := util.LuaCodePayload(l._payload)
code := string(payload.Code())
byteCode, err := contract.Compile(code, nil)
if err != nil {
return err
}
l._payload = util.NewLuaCodePayload(byteCode, payload.Args())
}
return contractFrame(l, bs, bc, receiptTx,
func(sender, contractV *state.AccountState, contractId types.AccountID, eContractState *statedb.ContractState) (string, []*types.Event, *big.Int, error) {
contractV.State().SqlRecoveryPoint = 1
Expand Down
36 changes: 0 additions & 36 deletions contract/vm_dummy/vm_dummy_dbg.go

This file was deleted.

28 changes: 0 additions & 28 deletions contract/vm_dummy/vm_dummy_release.go

This file was deleted.

8 changes: 4 additions & 4 deletions tests/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ wait_version() {
get_deploy_args() {
contract_file=$1

#if [ "$fork_version" -ge "4" ]; then
# deploy_args="$contract_file"
#else
if [ "$fork_version" -ge "4" ]; then
deploy_args="$contract_file"
else
../bin/aergoluac --payload $contract_file > payload.out
deploy_args="--payload `cat payload.out`"
#fi
fi

}

Expand Down
Loading