EOSIO / eos

An open source smart contract platform
https://developers.eos.io/manuals/eos
MIT License
11.27k stars 3.6k forks source link

Recover public key in contract #5076

Closed eosbet-io closed 5 years ago

eosbet-io commented 6 years ago

Say we have an arbitrary EOS public key: EOS8F5PUWEA8tVHYLwueZQ6wrsxwJLvog5D2KAy9g7bdTU7iY9qDU

How to get this into type public_key which is a char[34]? Seems like we must use this type with the built-in function assert_recover_key or it fails.

Say we have an arbitrary EOS signature: SIG_K1_KhHP1KdoRPw3izzovoTG4fnREiswPAGXhkq1WBz97CZ1ZEiukjuz9iooGc9jjGTKsz427BJQLrS3V1i1TR2Qq2ErTPMD7F

How do we get this into type signature which is a uint8_t[66]? We also need to use this specific type with the recover_key function.

This is really unclear and with zero documentation.

eosbet-io commented 6 years ago

See https://github.com/EOSIO/eos/blob/master/contracts/eosiolib/types.h for the underlying types to public_key and signature.

alexander-molina commented 6 years ago

That works for me. void test::foo(const checksum256 digest, const signature sig, const eosio::public_key pub) { public_key pub2; pub2.data[0] = char(pub.type.value); memcpy(&pub2.data[1], pub.data.data(), 33); assert_recover_key(&digest, (const char)&sig, sizeof(signature), (const char)&pub2, sizeof(public_key)); }

miguelmota commented 5 years ago

This worked for me

#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>
#include <eosiolib/crypto.h>
using namespace eosio;

class ec: public eosio::contract {
  public:
      using contract::contract;

  ///@abi action
  void ecverify(std::string data, const signature &sig, const public_key &pk)
  {
    checksum256 digest;
    sha256(&data[0], data.size(), &digest);

    assert_recover_key(&digest, (const char *)&sig, sizeof(sig), (const char *)&pk, sizeof(pk));
    print("VALID");
  }
};

EOSIO_ABI( ec, (ecverify) )
yuval-weiss commented 5 years ago

This worked for me

#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>
#include <eosiolib/crypto.h>
using namespace eosio;

class ec: public eosio::contract {
  public:
      using contract::contract;

  ///@abi action
  void ecverify(std::string data, const signature &sig, const public_key &pk)
  {
    checksum256 digest;
    sha256(&data[0], data.size(), &digest);

    assert_recover_key(&digest, (const char *)&sig, sizeof(sig), (const char *)&pk, sizeof(pk));
    print("VALID");
  }
};

EOSIO_ABI( ec, (ecverify) )

Any idea why I'm getting a "unknown type name 'signature'" and a "unknown type name 'public_key'" on compilation?

smlu commented 5 years ago

@yuval-weiss If you're using eosio.cdt v1.3.x, those types were renamed to capi_public_key and capi_signature. You can check types.h header file to get the correct name of those types.

chrisli30 commented 5 years ago

My error:

cleos push action betxdice resolvebet '["9870022816244567226","SIG_K1_KfgvshunycNajoe4b6NYgM6fi9rJJt3HiY9cukewbravDVEkZ9Wx6AcZXk3ierQWKok79vuyWXcWUp37iWfmZQR4E2XRuZ"]' -p betxdice@active

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.

Guys, how do I generate a signature and pass in as the second parameter? I'm using cleos sign -k {private_key} -c {chain_id} '{"seed":"b573137b8db841e11363e8f485c96665dbaab7ea3fcc1e4f8f8314c823d4c087"}' to generate a signature for function

[[eosio::action]] void resolvebet(const uint64_t bet_id, capi_signature sig) {
......
    assert_recover_key(&activebets_itr->seed, (const char *)&sig, sizeof(sig), (const char *)&rand_signing_key, sizeof(rand_signing_key));
......

in which &activebets_itr->seed and rand_signing_key are known by me.

The dilemma is that a signature is needed in parameter list, but I won't be able to generate it without constructing the transaction object. Kinda run into a chick-and-egg problem... Should I sign the whole transaction or just an object?

Please help ...