EOSIO / eosjs

General purpose library for the EOSIO blockchain.
http://eosio.github.io/eosjs
MIT License
1.43k stars 463 forks source link

Code hash verification #11

Closed nanonano7 closed 5 years ago

nanonano7 commented 6 years ago

I think adding an optional code hash verification would be good feature to have. So when i do a eos.contract(code<string>, [options], [callback]) i could also pass in a hash that the code hash has to match. Maybe like this eos.contract(code<string>, {hash:some_hash}, [callback])

jcalfee commented 6 years ago

The contract name is registered on the blockchain and in the case of a immutable contract should be as valid as a hash. I'm not sure how you would use this.. What is the concern here?

nanonano7 commented 6 years ago

It can be used to make the ui thats using it only work with the version of the contract it has the hash for. For example if i have contract and a ui app for it that people have downloaded. If i update the contract the ui will notice the code hash change and might tell the user that there has been a change in the code and they should check for an ui update. If we would use just the name and the contract gets changed either because the devs of the contract got hacked or by a legit update the ui would accept it either way even if it wasnt compatible/secure. An ui dev could implement this check himself but this addition would make it easier if you wanted to have this check in place for contracts that arent suppose to change.

jcalfee commented 6 years ago

I see.. Did you see this?

> eos.getCode('currency', (e,o)=>console.log(o.code_hash))
> 7dce087f0db3e91b12a97c72416d304f694194a8daf9ff519b9e76d26468db11
jcalfee commented 6 years ago

I think your right here.. eos.contract is already calling get_code with returns the hash so it would be better to make that information available. I think it is better to provide the hash though so you can make a decision if it will be valid or not.

The promise does not allow for a 2nd parameter (like code_hash, or {code_hash}). I don't want to crowd the contract object and create a potential function name conflict. I'll have to think about this..

jcalfee commented 6 years ago

I'm starting to see full-circle on this and can find no better way than what you suggested. I'll see if I can get it implemented.

const options = {hash:some_hash}
eos.contract(code<string>, options, [callback])
jcalfee commented 6 years ago

As a side note, it is possible to revoke permissions and make a contract immutable:

from @bytemaster remove all permissions from the account or remove owner/active and configure "setcode" to be null permission other configured permissions can remain active

Wouldn't it be more useful to notify the user if the contract changes and give them the option to accept it? What kind of UI are you planning to use this in?

jcalfee commented 6 years ago

Checking the hash when fetching the contract is reasonable but not atomic. There is discussion of a blockchain level feature to have this related to the transaction. If we get close to release time and that is not done this could be something to do in the mean time.

chris-allnutt commented 6 years ago

@jcalfee we've also brought this up with the C++ devs around our concern of creating accounts thru our web UI. We don't want to submit transactions we know are going to fail.

nsjames commented 6 years ago

This would be a useful feature. Similar to Couchbase's CAS value which can be used to check versioning. I suppose in the end it will simply become a checksum of the contract's binary data which can be fetched when creating an application on top of a contract and used to validate it's version upon every transaction from that point on.

Though, it should be clearly specified that this would add overhead and should only be used on contracts you do not own.

jcalfee commented 6 years ago

The feature as described above would add overhead and may need to be deprecated later.

The back-end could either:

The later is much less over-head on storage .. Transactions should have a recent block anyways to protect against all kinds of things (contentious fork for example).

amolmaid commented 6 years ago

Hi @jcalfee , Does scatterEos.getCode(account_name) is not supported anymore, as it shows following error msg for mainnet and jungle testnet while it works fine on local. get code err 2018-09-11 15-16-46

Please let me know if there is any way by which I can know if certain contract is published on an account or not ?

chris-allnutt commented 6 years ago

@amolmaid if scatter supports it you can do getabi potentially. This would be a better question for @nsjames since this is an implementation in Scatter.

amolmaid commented 6 years ago

@chris-allnutt , you meant getCode right ? I talked with James, getCode is deprecated; so do we got an alternative for the similar task?

jcalfee commented 6 years ago

Is the mongodb plugin available?

chris-allnutt commented 6 years ago

@amolmaid I think the only way to accomplish that now would be running a node with the mongo plugin, and using something like demux to capture the code you care about. Otherwise, I'd ask under the main eosjs repo, eosjs can only interact with the API endpoints provided by the chain API.

amolmaid commented 6 years ago

@jcalfee Currently I am not using mongodb plugin. I am really not sure why eosio deprecated get code, I mean its just a read only api anyway.

@chris-allnutt thanks for the this, but I'll need to talk to my project managers if its really important to have this feature, as we were just confirming if certain contract has been published or not on user's account; And Even if I republish it, it'll simply gonna throw an exception, so this is one way of dealing with it too.

So thank you for your quick help.

chris-allnutt commented 6 years ago

@amolmaid unless you want to run the MongoDB plugin and nodeos to fill it that may need to be your approach, unfortunately. If this is a contract you control then maybe you could add a basic authed action to verify the existence or a get_table for a table that contains specific data you'd expect. Good luck!

jcalfee commented 6 years ago

This might help:

https://github.com/EOSIO/eosjs-api/blob/master/docs/api.md#eos.getCodeHash published in eosjs@16.0.7

amolmaid commented 6 years ago

@jcalfee Thank you for upgrade, But I am not able to make it work. I have upated the eosjs version to 16.0.7 and used the method syntax as eos.getCodeHash(account_name) but its throwing me following exception. get code error

Please check my code snippet, screenshot from 2018-09-12 12-24-20

Note : I am able to see the getCodeHash() method in my eosScatter object after console.log() too.

Please let me if there is more to it which I might have skipped ?

jcalfee commented 6 years ago

Your right .. that API was part of the plan but I see it is not available anymore.

@heifner, while we move to mongodb is there a way to verify code deployed under an account? See above, at one point we merged get_code_hash but that has since been removed.

heifner commented 6 years ago
amolmaid commented 6 years ago

Hi @heifner

get_code don't work anymore, its been deprecated in eosoi.

heifner commented 6 years ago
Sabrinsulthana commented 6 years ago

@jcalfee Hi friend, while running this project i didnt get the hash code..please give a demo of this project to work on it