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

add system.toAddress() and system.toPubkey() #193

Merged
merged 17 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from 16 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
82 changes: 80 additions & 2 deletions contract/system_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,56 @@ static int lua_random(lua_State *L) {
return 1;
}

static int toPubkey(lua_State *L) {
char *address, *ret;

lua_gasuse(L, 100);

// get the function argument
address = (char *)luaL_checkstring(L, 1);
// convert the address to public key
ret = luaToPubkey(L, address);

if (ret == NULL) {
lua_pushnil(L);
} else {
// if the returned string starts with `[`, it's an error
if (ret[0] == '[') {
strPushAndRelease(L, ret);
luaL_throwerror(L);
} else {
strPushAndRelease(L, ret);
}
}

return 1;
}

static int toAddress(lua_State *L) {
char *pubkey, *ret;

lua_gasuse(L, 100);

// get the function argument
pubkey = (char *)luaL_checkstring(L, 1);
// convert the public key to an address
ret = luaToAddress(L, pubkey);

if (ret == NULL) {
lua_pushnil(L);
} else {
// if the returned string starts with `[`, it's an error
if (ret[0] == '[') {
strPushAndRelease(L, ret);
luaL_throwerror(L);
} else {
strPushAndRelease(L, ret);
}
}

return 1;
}

static int is_contract(lua_State *L) {
char *contract;
int service = getLuaExecContext(L);
Expand Down Expand Up @@ -461,7 +511,7 @@ static int is_fee_delegation(lua_State *L) {
return 1;
}

static const luaL_Reg sys_lib[] = {
static const luaL_Reg system_lib_v1[] = {
{"print", systemPrint},
{"setItem", setItem},
{"getItem", getItem},
Expand All @@ -483,8 +533,36 @@ static const luaL_Reg sys_lib[] = {
{NULL, NULL}
};

static const luaL_Reg system_lib_v4[] = {
{"print", systemPrint},
{"setItem", setItem},
{"getItem", getItem},
{"getSender", getSender},
{"getCreator", getCreator},
{"getTxhash", getTxhash},
{"getBlockheight", getBlockHeight},
{"getTimestamp", getTimestamp},
{"getContractID", getContractID},
{"getOrigin", getOrigin},
{"getAmount", getAmount},
{"getPrevBlockHash", getPrevBlockHash},
{"date", os_date},
{"time", os_time},
{"difftime", os_difftime},
{"random", lua_random},
{"toPubKey", toPubkey},
{"toAddress", toAddress},
{"isContract", is_contract},
{"isFeeDelegation", is_fee_delegation},
{NULL, NULL}
};

int luaopen_system(lua_State *L) {
luaL_register(L, "system", sys_lib);
if (vm_is_hardfork(L, 4)) {
luaL_register(L, "system", system_lib_v4);
} else {
luaL_register(L, "system", system_lib_v1);
}
lua_pop(L, 1);
return 1;
}
33 changes: 33 additions & 0 deletions contract/vm_callback.go
Original file line number Diff line number Diff line change
Expand Up @@ -1261,6 +1261,39 @@ func luaEvent(L *LState, service C.int, eventName *C.char, args *C.char) *C.char
return nil
}

//export luaToPubkey
func luaToPubkey(L *LState, address *C.char) *C.char {
// check the length of address
if len(C.GoString(address)) != types.EncodedAddressLength {
return C.CString("[Contract.LuaToPubkey] invalid address length")
}
// decode the address in string format to bytes (public key)
pubkey, err := types.DecodeAddress(C.GoString(address))
if err != nil {
return C.CString("[Contract.LuaToPubkey] invalid address")
}
// return the public key in hex format
return C.CString("0x" + hex.Encode(pubkey))
}

//export luaToAddress
func luaToAddress(L *LState, pubkey *C.char) *C.char {
// decode the pubkey in hex format to bytes
pubkeyBytes, err := decodeHex(C.GoString(pubkey))
if err != nil {
return C.CString("[Contract.LuaToAddress] invalid public key")
}
// check the length of pubkey
if len(pubkeyBytes) != types.AddressLength {
return C.CString("[Contract.LuaToAddress] invalid public key length")
// or convert the pubkey to compact format - SerializeCompressed()
}
// encode the pubkey in bytes to an address in string format
address := types.EncodeAddress(pubkeyBytes)
// return the address
return C.CString(address)
}

//export luaIsContract
func luaIsContract(L *LState, service C.int, contractId *C.char) (C.int, *C.char) {

Expand Down
11 changes: 11 additions & 0 deletions contract/vm_dummy/test_files/contract_system.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,14 @@ function testState()
end

abi.register(testState)


function to_address(pubkey)
return system.toAddress(pubkey)
end

function to_pubkey(address)
return system.toPubKey(address)
end

abi.register_view(to_address, to_pubkey)
47 changes: 47 additions & 0 deletions contract/vm_dummy/vm_dummy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,53 @@ func TestContractSystem(t *testing.T) {
exRv := fmt.Sprintf(`["%s","6FbDRScGruVdATaNWzD51xJkTfYCVwxSZDb7gzqCLzwf","AmhNNBNY7XFk4p5ym4CJf8nTcRTEHjWzAeXJfhP71244CjBCAQU3",%d,3,999]`, StrToAddress("user1"), bc.cBlock.Header.Timestamp/1e9)
assert.Equal(t, exRv, receipt.GetRet(), "receipt ret error")

if version >= 4 {

// system.toPubKey()

err = bc.Query("system", `{"Name":"to_pubkey", "Args":["AmgKtCaGjH4XkXwny2Jb1YH5gdsJGJh78ibWEgLmRWBS5LMfQuTf"]}`, "", `"0x0c3270bb25fea5bf0029b57e78581647a143265810b84940dd24e543ddc618ab91"`)
require.NoErrorf(t, err, "failed to query")

err = bc.Query("system", `{"Name":"to_pubkey", "Args":["Amhmj6kKZz7mPstBAPJWRe1e8RHP7bZ5pV35XatqTHMWeAVSyMkc"]}`, "", `"0x0cf0d0fd04f44db75d66409346102167d67c40a5d76d46748fc4533f0265d0f83f"`)
require.NoErrorf(t, err, "failed to query")

err = bc.Query("system", `{"Name":"to_pubkey", "Args":["6FbDRScGruVdATaNWzD51xJkTfYCVwxSZDb7gzqCLzwf"]}`, "invalid address length", "")
require.NoErrorf(t, err, "failed to query")

err = bc.Query("system", `{"Name":"to_pubkey", "Args":["0x0c3270bb25fea5bf0029b57e78581647a143265810b84940dd24e543ddc618ab91"]}`, "invalid address length", "")
require.NoErrorf(t, err, "failed to query")

err = bc.Query("system", `{"Name":"to_pubkey", "Args":[""]}`, "invalid address length", "")
require.NoErrorf(t, err, "failed to query")

err = bc.Query("system", `{"Name":"to_pubkey", "Args":[]}`, "string expected, got nil", "")
require.NoErrorf(t, err, "failed to query")

// system.toAddress()

err = bc.Query("system", `{"Name":"to_address", "Args":["0x0c3270bb25fea5bf0029b57e78581647a143265810b84940dd24e543ddc618ab91"]}`, "", `"AmgKtCaGjH4XkXwny2Jb1YH5gdsJGJh78ibWEgLmRWBS5LMfQuTf"`)
require.NoErrorf(t, err, "failed to query")

err = bc.Query("system", `{"Name":"to_address", "Args":["0x0cf0d0fd04f44db75d66409346102167d67c40a5d76d46748fc4533f0265d0f83f"]}`, "", `"Amhmj6kKZz7mPstBAPJWRe1e8RHP7bZ5pV35XatqTHMWeAVSyMkc"`)
require.NoErrorf(t, err, "failed to query")

err = bc.Query("system", `{"Name":"to_address", "Args":["0cf0d0fd04f44db75d66409346102167d67c40a5d76d46748fc4533f0265d0f83f"]}`, "", `"Amhmj6kKZz7mPstBAPJWRe1e8RHP7bZ5pV35XatqTHMWeAVSyMkc"`)
require.NoErrorf(t, err, "failed to query")

err = bc.Query("system", `{"Name":"to_address", "Args":["AmhNNBNY7XFk4p5ym4CJf8nTcRTEHjWzAeXJfhP71244CjBCAQU3"]}`, "invalid public key", "")
require.NoErrorf(t, err, "failed to query")

err = bc.Query("system", `{"Name":"to_address", "Args":["6FbDRScGruVdATaNWzD51xJkTfYCVwxSZDb7gzqCLzwf"]}`, "invalid public key", "")
require.NoErrorf(t, err, "failed to query")

err = bc.Query("system", `{"Name":"to_address", "Args":[""]}`, "invalid public key", "")
require.NoErrorf(t, err, "failed to query")

err = bc.Query("system", `{"Name":"to_address", "Args":[]}`, "string expected, got nil", "")
require.NoErrorf(t, err, "failed to query")

}

}
}

Expand Down
Loading