0

my Question in short is:

-> is it possible to digitally sign some data by a smart contract (e.g. with a secret key of the contract) and thus confirm that it was exactly this smart contract, who signed the data? -> I already kind of know, that it probably won't work that way, because a contract's data and code is entirely public and thus it can't keep a secret. So are there any clever on-chain workarounds, or would I have to use off-chain steps with this one..?

Now with a bit of background:

I'm trying to create a dapp, in which a creator can sign a document and have it timestamped on the Blockchain, so that anyone can verify wether the document existested at a certain point in time.

My concept so far was:

  1. Document gets hashed and then signed by the creator's private key (client side, off chain) -> thus creating a digital signature of the document

  2. The signature is then sent to a smart contract, which appends a timestamp to the signature, hashes both together and then the contract signes the hash)(the timestamp represents the current block's time)

  3. The Contract stores a mapping where each row (one row for each document or its version) is accessed with the hash of the document, pointing to a struct with: the timestamp, the signature of the creator and the timestamp signed by the contract itself.

  4. Now anyone with access to the document, the creators public key and the contracts public key could verify (with the signed hashes in the mapping), that

a) the document was signed by the creator

b) the document was timestamped and signed by the smart contract

-> My original goal was to avoid having trusted third parties included into the process at all (neither for timestamping, nor signing)

So the Problems seem to be:

-> since a smart contract cannot store a secret on chain(as far as I know), I cannot securely store a private key in the contract, with which it could sign data

-> also, if I stored a secret key somewhere off chain, how could a smart contract be authorized to access it? (since it has no private key to be identified with)

It would really be awesome if you could help me out! Thank you!

1 Answer 1

2

is it possible to digitally sign some data by a smart contract (e.g. with a secret key of the contract)

No. Contracts don't have signing keys, can't initiate action (it always starts with a transaction signed by an externally owned account) and can't interact with the outside world except by emitting events into logs.

I'm trying to create a dapp, in which a creator can sign a document and have it timestamped on the Blockchain, so that anyone can verify wether the document existested at a certain point in time.

That isn't especially hard ...

Document gets hashed and then signed by the creator's private key (client side, off chain) -> thus creating a digital signature of the document

Yep

The signature is then sent to a smart contract, which appends a timestamp to the signature, hashes both together

You get the timestamp for "free" when the transaction is included in a block. The extra steps seem to make it worse. You want observers to be able to confirm the doc (in the future) and they shouldn't be required to know that timestamp in order to do so. Just record the hash of the contents.

mapping(bytes32 => bool) public exists;

function recordExistence(bytes32 docHash) public returns(bool success) {
  require(!exists[docHash]);
  exists[docHash] = true;
  // should emit an event, omitted for brevity
}

and then the contract signes the hash)(the timestamp represents the current block's time)

There is no contract signature step, per se. If the contract allows it, that's that. It's not possible for any state transition to occur unless the contract approves.

The Contract stores a mapping where each row (one row for each document or its version) is accessed with the hash of the document, pointing to a struct with: the timestamp, the signature of the creator and the timestamp signed by the contract itself.

You can go with the plain address of the creator because the creator will be the signer who sent the transaction. I'll put the time in for the heck of it, but it's probably not needed.

struct DocStruct {
  address creator;
  uint timestamp;
}

mapping(bytes32 => DocStruct) public docStructs;

function docExists(bytes32 docId) public view returns(bool doesIndeed) {
  return docStructs[docId].timestamp > 0;
}

function recordDocCreated(bytes32 docHash) public view returns(bool success) {
  require(!docExists[docHash]);
  docStructs[docId].creator = msg.sender;
  docStructs[docId].timestamp = now;
  // emit ... 
  return true;
}

Now anyone with access to the document, the creators public key and the contracts public key could verify (with the signed hashes in the mapping), that

a) the document was signed by the creator

b) the document was timestamped and signed by the smart contract

Yes. msg.sender does not lie, nor does now. Overwrite is not possible.

My original goal was to avoid having trusted third parties included into the process at all (neither for timestamping, nor signing)

So the Problems seem to be:

-> since a smart contract cannot store a secret on chain(as far as I know), I cannot securely store a private key in the contract, with which it could sign data

Click your heels together, you're already home. AFAIK, the hash of the document isn't meant to be a secret. It says nothing useful about the document other than it exists. You've got proof that the creator signed a message demonstrating knowledge of that secret at a certain time.

The transaction the signer (creator) sent was mined into a block with a definite timeStamp. When someone inspects the public docStructs with the docHash in question, the returned values are trust-worthy.

The only known viable (Alice doesn't have a time machine) explanation is the creator signed a transaction with knowledge of the document (and computed its hash) at a provable point in history. There is no way she guessed that hash unless she had the document.

This is a common approach. If you need more granular proofs about what's in the document while keeping the adjacent information secret: https://medium.com/@robhitchens/selective-disclosure-with-proof-f6a1ac7be978

Hope it helps.

1
  • great answer! Thank you very much. I'm pretty new in the area so I'm still trying to get my head around dapps, but your answer really helped! Thanks again!
    – Johannes K
    Oct 12, 2018 at 8:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.