EOS front end with javascript

This I guess is outside the scope of the course, but I thought I would try to do front end for EOS with eosjs, similar to ethereum and web3. I can not get the authorization.

Eos = require('eosjs')

eos = Eos({keyProvider: [keys],
    expireInSeconds: 60,

})

eos.contract('fred.abc').then(c => {
    // hello storage contract from the course
    c.hello({username: 'fred.xyz', full_name: "Fred Flintstone"}, { 
        authorization: 'fred.xyz@active',
        broadcast: true,
        sign: true
      }).then(r => {
        console.log(r)
    })
})

if I set broadcast: false I seem to get a valid signed transaction, but set to true I get an authorization error

I tried upgrading my installation, thinking maybe the eosjs may not be compatible with the dawn version,to v1.0.6 but I get an error Not producing block because I don't have the private key for EOS8Znrtgwt8TfpmbVpTKvA2oB8Nqey625CLN8bCN3TEbgx86Dsvr

I’m getting the exact same bug now… I had actions all working a few weeks ago and it seems they’ve change something? Here’s my issue on GitHub.

Got bored waiting for a reply from the EOSjs team, so made this little react form element.

my error is different

"provided keys, permissions, and delays do not satisfy declared authorizations","details":[{"message":"transaction declares authority '{\"actor\":\"fred.xyz\",\"permission\":\"active\"}', but does not have signatures for it under a provided delay of 0 ms","file":"authorization_manager.cpp","line_number":405,"method":"check_authorization"}]

but like I said, if I don’t broadcast, I get a signature returned with the transaction

Yes the Broadcast function just signs the transaction and returns it too you. In the case of no network connectivity, like a cold storage wallet, you could store this transaction for later broadcast, but the signature would probably fail when the network attempts to validate.

It sounds like your active key for fred.xyz is not stored under the wallet for your EOSjs keyProvider?
Try running;

cleos wallet list
// To see your wallets (*) means unlocked
cleos wallet unlock
/** For default OR the following for a named wallet **/
cleos wallet unlock -n myWallet2
// And enter your secret key to unlock the wallet
cleos wallet keys
// Lists all the keys for accounts, copy one
cleos get accounts MY_COPIED_WALLET KEY
// Lists all the accounts under that key
cleos get account fred.xyz
// Lists the account's permission keys and stats

At the end, the EOSjs keyProvider your signing with should hold the keys which are linked to the fred.xyz accounts @active permission, where your error is saying it’s not.

I got it working, I got a message saying

chainId mismatch, signatures will not match transaction authority. expected cf057b... !== actual 706a7...

eos = Eos({keyProvider: [keys],
    expireInSeconds: 60,
    chainId: "706a7..." // actual
})

So did you manage to call an action on your contract after this? I’m having trouble still…

Yes, I successfully call the action and verify the data in the table

Would I be able to grab a copy of your initialisation and action calling code? I just can’t get mine to execute.

additional experimentation added also for creating account

(async () => {
    Eos = require('eosjs')
    const ecc = Eos.modules.ecc
    let eos

    let promises = [], keys = [], keyPairs = []
    for(let i=0; i<5; i++) {
        promises.push(ecc.randomKey())
    }
    const kys = await Promise.all(promises)
    keys = kys
    keyPairs = keys.map(k => {
        return {private: k, public: ecc.privateToPublic(k)}
    })
    console.log(JSON.stringify(keyPairs, null, 2))

    eos = Eos({keyProvider: ["5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"].concat(keys), // fred.abc key plus newly created
        expireInSeconds: 60,
        chainId: "706a7ddd808de9fc2b8879904f3b392256c83104c1d544b38302cc07d9fca477" // cleos get info - to get this
    })

    const pubkey = keyPairs[0].public
    eos.transaction(tr => {
        tr.newaccount({
          creator: 'eosio',
          name: 'myaccount',
          owner: pubkey,
          active: pubkey
        })
        
      })

    let c = await eos.contract('fred.abc')

    let r = await c.add({username: 'myaccount', full_name: "Auto Gen 4"}, {
        authorization: 'myaccount',
        broadcast: true,
        sign: true
    })
    console.log(JSON.stringify(r, null, 2))
    let t = await eos.getTableRows({
        code: "fred.abc",
        scope: "fred.abc",
        table: "log",
        json: true
    })
    console.log(JSON.stringify(t,null,2))
})()

contract

deployed contract with account fred.abc, slightly modified from course to allow update and show account name along with id

#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>

using namespace eosio;
using std::string;

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

    /// @abi action
    void add(const name username, const string& full_name){
        require_auth(username);
        print("Hello, ", name{username});
        addEntry(username, name{username}.to_string(), full_name);
    }

    private:
    /// @abi table log i64
    struct log{
        uint64_t username;
        string str_name;
        string full_name;
        uint64_t primary_key() const {return username;}

        EOSLIB_SERIALIZE(log, (username)(str_name)(full_name));
    };


    typedef multi_index<N(log), log> helloIndex;

    void addEntry(const name username, const string& str_name, const string& full_name){
        helloIndex entries(_self, _self);
        auto iterator = entries.find(username);
        if(iterator == entries.end())
            entries.emplace(username, [&](auto& logEntry){
                logEntry.username = username;
                logEntry.str_name = str_name;
                logEntry.full_name = full_name;
            });
        else
            entries.modify(iterator, username, [&](auto& logEntry){
                logEntry.username = username;
                logEntry.str_name = str_name;
                logEntry.full_name = full_name;
            });

    }

};

EOSIO_ABI(hello, (add))

Thank you! So far I figured out one of my contracts has somehow been running for two days using a string library that wasn’t even linked correctly. It suddenly started corrupting my string values in tables. Still working on this public key problem.

I finally solved my issues, turns out I was using the wallet password instead of the secret key, they look almost identical!

Thanks for your help and sharing your code @rbondi

1 Like