Open Patrick-Shih opened 5 years ago
I guess that you need to have eosio system contracts installed in order to be able to refer to the eosio.code
permission.
Within several days I will workout the issue.
Sorry, I see that my previous comment is stupid. Nevertheless, I will solve the issue.
Evidently, EOSIO does not like giving permissins to itself. Change str(alice)
to carol
.
You do not need to convert account object to string in the actor
field. The conversion is needed if there is many actors: EOSIO has them sorted lexicographically. Therefore, in the tutorial actors physical names are sorted, being converted to strings.
Hi @stefanzarembinski,
Appreciate for the timely feedback. I think giving permission to other account does not solve the problem. It is a common use case on EOS mainnet to add eosio.code permission to some account to grant permission to contract's inner action with following cleos command:
cleos set account permission testaccount1 active --add-code
Meanwhile, testaccount1 should also be able to do something (call other contract's action) as a normal account with testaccount1@active permission.
I have tried remove the str() without change account (it is not what I want) but no luck it shows the same ERROR.
Or is there any way to just add eosio.code permission to an account without manually set all the permissions. Maybe something like
alice.add_code()
Today, we are going to publish a new edition of EOSFactory. There is there a folder archive
, see the arbitration
contract example. In the tests
folder, you can find the test1.md
file: it can be executed as a python script:
eosfactory/pythonmd.sh archive/arbitration/tests/test1.md
The contract solves a case of interaction between smart contracts, using the eosio.code
permission:
ESCROW.set_account_permission(Permission.ACTIVE,
{
"threshold": 1,
"accounts":
[
{
"permission":
{
"actor": ESCROW,
"permission": "eosio.code"
},
"weight":1
}
]
},
Permission.OWNER
)
I hope, the example may be useful to you.
If you do not want to wait for the publication, see the branch pypi-ready
.
You suggest a special syntax for the eosio.code
permission setting. I will wait until you repeat it after gaining experience with permissions in EOSFactory.
Hi @stefanzarembinski,
I have upgraded to EOSfactory 3.0.1 and retry what you say. The result is, still, Error 3090003
As stated in my first post, the issue is not on setting the eosio.code
permission, it works perfectly.
However, after setting the eosio.code
permission, the original account@active
is failing.
The issue is how to keep both eosio.code
and account@active
permission
For example using the eosio hello world contract with the following test code
import sys
from eosfactory.eosf import *
verbosity([Verbosity.INFO, Verbosity.OUT, Verbosity.DEBUG])
CONTRACT_WORKSPACE = sys.path[0] + "/../"
def test():
reset()
create_master_account("master")
create_account("host", master)
create_account("alice", master)
contract = Contract(alice, "directory of the hello contract")
contract.build(force=False)
contract.deploy()
alice.info()
COMMENT('alice say hi:')
alice.push_action("hi", {"user": alice}, permission=(alice, Permission.ACTIVE))
COMMENT('Add eosio.code permission to alice:')
alice.set_account_permission(Permission.ACTIVE,
{
"threshold": 1,
"accounts":
[
{
"permission": {
"actor": alice,
"permission": "active"
},
"weight": 1
},
{
"permission": {
"actor": alice,
"permission": "eosio.code"
},
"weight": 1
}
]
}, Permission.OWNER
)
alice.info()
COMMENT('alice say hi again:')
alice.push_action("hi", {"user": alice}, permission=(alice, Permission.ACTIVE))
stop()
if __name__ == "__main__":
test()
The first alice.push_action("hi", {"user": alice}, permission=(alice, Permission.ACTIVE))
will success, but the second will fail
Here are the console output start from the first alice.info()
Account object name: alice
name: nc5tf5izwwgs
created: 2019-03-06T11:00:13.000
permissions:
owner 1: 1 alice@owner
active 1: 1 alice@active
memory:
quota: unlimited used: 24.97 KiB
net bandwidth:
used: unlimited
available: unlimited
limit: unlimited
cpu bandwidth:
used: unlimited
available: unlimited
limit: unlimited
### test:
alice say hi:
* push action ``hi``:
{"user": "alice"}
Hello, alice
### test:
Add eosio.code permission to alice:
* account permission ``{'threshold': 1, 'accounts': [{'permission': {'actor': , 'permission': 'active'}, 'weight': 1}, {'permission': {'actor': , 'permission': 'eosio.code'}, 'weight': 1}]}``:
Account object name: alice
name: nc5tf5izwwgs
created: 2019-03-06T11:00:13.000
permissions:
owner 1: 1 alice@owner
active 1: 1 alice@active, 1 alice@eosio.code
memory:
quota: unlimited used: 24.99 KiB
net bandwidth:
used: unlimited
available: unlimited
limit: unlimited
cpu bandwidth:
used: unlimited
available: unlimited
limit: unlimited
### test:
alice say hi again:
ERROR /Users/shedoh/Dropbox/workspace/acxel/eosfactory/eosfactory/core/errors.py 44:
Error 3090003: Provided keys, permissions, and delays do not satisfy declared authorizations
Ensure that you have the related private keys inside your wallet and your wallet is unlocked.
Error Details:
transaction declares authority '{"actor":"alice","permission":"active"}', but does not have signatures for it.
I use the eosio.code
permission there. Please, try to compare our case with yours one. I will help you, if comparison does not solve the issue.
Thank you for the notion. I believe that the issue is not on the eosio.code
.
Anyway I try what your say by replace the set_account_permission part as follow
alice.set_account_permission(Permission.ACTIVE,
{
"threshold": 1,
"accounts":
[
{
"permission": {
"actor": alice,
"permission": "eosio.code"
},
"weight": 1
}
]
}, Permission.OWNER
)
alice.info()
The output...
Account object name: alice
name: q35ywewzk1do
created: 2019-03-08T06:22:47.000
permissions:
owner 1: 1 alice@owner
active 1: 1 alice@active
memory:
quota: unlimited used: 24.97 KiB
net bandwidth:
used: unlimited
available: unlimited
limit: unlimited
cpu bandwidth:
used: unlimited
available: unlimited
limit: unlimited
### test:
alice say hi:
* push action ``hi``:
{"user": "alice"}
Hello, alice
### test:
Add eosio.code permission to alice:
* account permission ``{'threshold': 1, 'accounts': [{'permission': {'actor': , 'permission': 'eosio.code'}, 'weight': 1}]}``:
Account object name: alice
name: q35ywewzk1do
created: 2019-03-08T06:22:47.000
permissions:
owner 1: 1 alice@owner
active 1: 1 alice@eosio.code
memory:
quota: unlimited used: 24.96 KiB
net bandwidth:
used: unlimited
available: unlimited
limit: unlimited
cpu bandwidth:
used: unlimited
available: unlimited
limit: unlimited
### test:
alice say hi again:
ERROR /Users/shedoh/Dropbox/workspace/acxel/eosfactory/eosfactory/core/errors.py 44:
Error 3090003: Provided keys, permissions, and delays do not satisfy declared authorizations
Ensure that you have the related private keys inside your wallet and your wallet is unlocked.
Error Details:
transaction declares authority '{"actor":"alice","permission":"active"}', but does not have signatures for it.
As you can see from the ouput, by setting only eosio.code
permission, alice not even have alice@active permission, and the failure is expected.
permissions:
owner 1: 1 alice@owner
active 1: 1 alice@eosio.code
Could you please try either my or your way to set the eosio.code
permission, and try if that account can perform any action that require its active permission (like eosio.token transfer, or any action that require_auth the caller).
BTW, when using cleos
, if the permission (alice@active is presented) is correct and key is presented, the error indicate that the wallet is locked. I believe EOSfactory must has done something in the backgroud to unlock the wallet or bypass it. Maybe there is something i missed to do, such as manually unlock the wallet again or the EOSfactory should do it again for me.
I will say that because I have try using EOSfactory on python interpreter. I create an account and do something then just leave it without stop the local test node. After some time and do the same action again, it show the Error 3090003. I do not know if these two are related or not, just for your reference.
Let us consider the command:
alice.set_account_permission(
Permission.ACTIVE, {
"threshold":
1,
"keys": [],
"accounts": [
{
"permission":
{
"actor": alice,
"permission": "active"
},
"weight": 1
},
{
"permission":
{
"actor": alice,
"permission": "eosio.code"
},
"weight": 1
}
]
}, Permission.OWNER, (alice, Permission.OWNER))
It implements the command cleos set account permission alice active {...} owner -p alice@owner
. The second argument which is active
is the name of the alice's permission to be set. In our case, the permission alice@active
has been previously defined, on the creation of the account, and the corresponding keys reside in the wallet.
Now, we execute the action:
HOST.push_action(
"hi", {"user":alice}, permission=(alice, Permission.ACTIVE))
The code of the action checks the authority of the user which is alice
. The permission shown is alice@active
. But alice@active
is redefined with the command set account permission
, and, therefore, cannot be verified with the wallet keys, valid before redefinition.
This is how I see the issue now. Am I wrong?
If you want to be sure about the status of the wallet, you can use the following commands:
get_wallet().open()
get_wallet().unlock()
print(get_wallet().keys())
Also, you can inspect all the calls to cleos
:
import eosfactory.core.setup as setup
is_print_command_line = True
This is your case but hello_world
is replaced with eosio_token
.
import sys, os
import eosfactory.core.config as config
from eosfactory.eosf import *
verbosity([Verbosity.INFO, Verbosity.OUT, Verbosity.DEBUG])
#CONTRACT_WORKSPACE = os.path.join(config.eosf_dir(), "contracts/hello_world")
CONTRACT_WORKSPACE = os.path.join(config.eosf_dir(), "contracts/eosio_token")
reset()
MASTER = new_master_account()
COMMENT('''
Build and deploy the contract:
''')
COMMENT('''
Create test accounts:
''')
ALICE = new_account(MASTER)
print(ALICE.active_key);
print(get_wallet().keys())
ALICE.set_account_permission(
Permission.ACTIVE, {
"threshold":
1,
"keys": [],
"accounts": [
{
"permission":
{
"actor": ALICE,
"permission": "active"
},
"weight": 1
},
{
"permission":
{
"actor": ALICE,
"permission": "eosio.code"
},
"weight": 1
}
]
}, Permission.OWNER, (ALICE, Permission.OWNER))
HOST = new_account(MASTER)
smart_contract = Contract(HOST, CONTRACT_WORKSPACE)
smart_contract.build(force=False)
smart_contract.deploy()
# HOST.push_action(
# "hi", {"user":ALICE}, permission=(ALICE, Permission.ACTIVE))
HOST.push_action(
"create",
{
"issuer": MASTER,
"maximum_supply": "1000000000.0000 EOS"
},
permission=[(MASTER, Permission.OWNER), (HOST, Permission.ACTIVE)])
HOST.push_action(
"issue",
{
"to": ALICE, "quantity": "100.0000 EOS", "memo": ""
},
permission=(MASTER, Permission.ACTIVE))
stop()
See the previous two comments. Here comes the third one.
You say:
BTW, when using cleos, if the permission (alice@active is presented) is correct and key is presented
The main feature of EOSFactory is its compatibility with plain cleos bash work. Will you, please, pass the bash script thet you mention?
I want to verify it against EOSFactory.
Thanks for the elaboration. I understand your point.
When using cleos
I always use --add-code
to add eosio.code
permission. After some survey I found it do the following things (ref)
cleos set account permission YOUR_CONTRACT active '{"threshold": 1,"keys": [{"key": "CURRENT_PUBLIC_KEY(S)_IN_ACTIVE_PERM","weight": 1}], "accounts": [{"permission":{"actor":"YOUR_CONTRACT","permission":"eosio.code"},"weight":1}]}' -p YOUR_CONTRACT@owner
I found an interesting note that
"keys": [{"key": "CURRENT_PUBLIC_KEY(S)_IN_ACTIVE_PERM","weight": 1}],
It appears that --add-code automatically add all current public keys into the keys field, and that is why I can still use original account@active permission.
I try the same thing by bring in the CURRENT_PUBLIC_KEY as follow when calling set_account_permission` and it WORKS!!
"keys": [{"key": ALICE.active_key.key_public, "weight":1 }],
Thanks you very much!
BTW, I still recommend to add something like alice.add_code()
since
key_public
field by read the code shell/account.py
, which is not on the document. I believe not every user knows and like to read the code.I am glad to see good news from you. Thank you for your persistance.
I will accept your advice. Please, elaborate it more: now I am overworked so much...
I am sorry for such a long delay: now I correct the method set_account_permission
so that the following expressions make sense:
HOST.set_account_permission(Permission.ACTIVE, add_code=True)
HOST.set_account_permission(Permission.ACTIVE, remove_code=True)
This improvement will be published soon (v3.1.3)
I see now that the last remark of mine, in the previous comment, proves that I really have been overworked then.
But, have you ever seen EOSIDE? It is a VSCode extension, available from the Marketplace. I would like to now your opinion on it, very much.
You must take care of your self ... 💪💪💪
Thanks for the info about EOSIDE, look wonderful for me. I am a little busy recently. Will give it a try and let you know my feedback then.
I follow https://eosfactory.io/build/html/patterns/set/set_account_permission.html#weights-and-threshold and try to add eosio.code permission to account as follow
The eosio.code permission is working but original alice@active is not working anymore. For example when doing a push action like
it shows
I do not know if this is a bug or I just use the wrong way to set permission?
BTW,
alice.info()
looks perfectMy environment