blockchainhyperledgerhyperledger-sawtooth

hyperledger sawtooth submit transaction error "Tried to get unauthorized address" with status invalid


the same question has been asked in here -> Sawtooth Transaction error: "Tried to set unauthorized address" and I tried that answer. But that answer didn't work for me.

i'm using hyperleder sawtooth docker compose to start my services. I'm doing exactly the same thing in this documentation which provided by hyperledger-sawtooth -> https://sawtooth.hyperledger.org/docs/core/releases/1.0/_autogen/sdk_submit_tutorial_js.html#create-the-transaction-header

My payload is

const payload = {
    Verb: 'set',
    Name: 'test',
    Value: 32
}

My transaction header is

const transactionHeaderBytes = protobuf.TransactionHeader.encode({
    familyName: 'intkey',
    familyVersion: '1.0',
    inputs: ['1cf1266e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7'],
    outputs: ['1cf1266e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7'],
    nonce: (Math.random() * 10 ** 18).toString(36),
    signerPublicKey: signer.getPublicKey().asHex(),
    batcherPublicKey: signer.getPublicKey().asHex(),
    dependencies: [],
    payloadSha512: createHash('sha512').update(payloadBytes).digest('hex')
}).finish()

Then i did the same process like in the documentation and when i check the status of that transaction, it gives me below response.

enter image description here

Then i check the log of the sawtooth server and it looked like below.

enter image description here

Then after seeing an answer the same question on here (Sawtooth Transaction error: "Tried to set unauthorized address"), I tried inputs and outputs arrays as empty arrays like []. But response was same.

My docker-compose file contains below containers

enter image description here


Solution

  • Setting empty arrays like [] to inputs and outputs is not an option. This would mean you're not letting any of the address read and write possible through your transaction processor. You can however set the partial address in inputs and outputs. For example, you can set 1cf126 for both inputs and outputs and your code will start working.

    Setting partial address would enable your TP to read and/or write any of the leaf node under the sub-tree your address points to. Refer to the https://sawtooth.hyperledger.org/docs/core/releases/1.0/architecture/global_state.html?#radix-merkle-tree-overview section to understand how that works.

    The example given in the documentation is for the intkey transaction family and the input is

    const payload = {
        Verb: 'set',
        Name: 'foo',
        Value: 32
    }
    

    But if you would like to set test instead of foo then you will have to calculate the address for it and place it in inputs and outputs. Note address calculation is something you keep consistent across a client and a TP for particular Transaction Family. The way intkey does it is by concatenating two of the following

    1. Sha512(intkey) - first 6 characters in hex representation
    2. Sha512(foo) - Rest of the characters from 64th index

    for foo.

    Ref: https://github.com/hyperledger/sawtooth-sdk-rust/blob/190861a14046122ce6ecd684908c3d7a877e26ca/examples/intkey_rust/src/handler.rs#L175

    In case of test this would be concatenation of

    1. Sha512(intkey) - first 6 characters in hex representation
    2. Sha512(test) - Rest of the characters from 64th index

    Hope this clarifies. Also, please refer to the Merkle-Radix definition above, it has detailed information on how address can be calculated. It is upto the implementer of Transaction Family.