Ethereum: How are SIGHASH tokens encoded as a signature?
Ethereum: How are SIGHASH flags encoded in a signature?
In Ethereum, signatures are used to prove ownership and copyright of transactions on the blockchain. One of the key components that enables this is the
SIGHASH (Signature Hash Algorithm) flag system. In this article, we will look at how SIGHASH flags are encoded in a signature.
What are SIGHASH flags?
SIGHASH flags allow the signer to control which parts of a transaction he wants to sign and verify. These flags allow for more efficient use of memory and computing resources on the Ethereum network.
A signature is created by hashing the input data with a public key, followed by hashing the resulting hash with a private key.
Encoding SIGHASH flags in a signature
If a signer wants to extract specific parts of a transaction to sign, they must encode their SIGHASH flag into a unique identifier that can be used for verification. This is done by extracting the required field from the input data and then mixing it with the private key.
Let’s assume we are working with a simple transaction example:
pragma hardness ^0,8,0;
contract SimpleTransaction {
function sendMoney(address receiver, uint amount) public {
// Input: sender, receiver and amount to be transferred
bytes32 _inputs = abi.encodePacked(sender, receiver, amount);
// Encode SIGHASH flags (OP_CHECKSIG)
SIGHASH[] memory _flags = new SIGHASH[_inputs.length];
for (uint i = 0; i < _inputs.length; i++) {
_flags[i] = SIGHASH(_inputs[i]);
}
// Hash the input with the private key
bytes32 _dataHash = abi.encodePacked(_inputs, msg.sender);
// Hash the result with the public key (OP_CHECKSIG)
bytes32 _sigHash = keccak256(abi.encodePacked(_dataHash, _flags));
// Sign the signature hash with the private key
bytes32 _sig;
if (message sender == address(0)) {
assembly {
_sig := sha3_256(note := abi.encodePacked(_sigHash))
}
} else {
_sig := keccak256(abi.encodePacked(_sigHash));
}
// Verify the signature
request(msg.sender == owner, "Invalid signature");
}
}
In this example, we encode the SIGHASH flags into a unique identifier using the “abi.encodePacked” function. We also hash the input data with the private key to create a hash value.
SIGHASH Flag Encoding
The “_flags” array contains one element for each flag, which is a
SIGHASH
structure that contains the following information:
- 0x1 (OP_CHECKSIG): Extracts the non-stack argument from each evaluated signature.
- Other flags (e.g. OP_CHECKSIGVERIFY, OP_CHECKSIGSIGN): Provide additional verification capabilities.
By encoding these flags into a unique identifier using the “_sigHash” variable, we can verify that the correct part of the transaction has been signed and verified.
Conclusion
In this article, we have explored how SIGHASH flags are encoded in a signature in Ethereum. By understanding how these flags work, you will be better prepared to optimize your code for better network performance. Remember to always follow best practices when working with cryptography and hash functions.