[untitled]
6 comments
Seems buggy.
In a proper blockchain each successive block depends on the previous ones. Thus, breaking 'foo' by replacing it with 'blah' should have also broken 'qux'.
In a proper blockchain each successive block depends on the previous ones. Thus, breaking 'foo' by replacing it with 'blah' should have also broken 'qux'.
Yes. The mistake is to only hash the data of the previous block. You should hash the whole previous block, including prev.prev.
Here's an implementation with lines of sql and pl/pgsql:
Given a table mytable with an pk id and say the fields 'block' and 'hash', replace it with mytable_changes and add an "internal" field called created_at of type "timestamp not null default now()".
Then create this trigger function (e.g. PostgreSQL):
Given a table mytable with an pk id and say the fields 'block' and 'hash', replace it with mytable_changes and add an "internal" field called created_at of type "timestamp not null default now()".
Then create this trigger function (e.g. PostgreSQL):
create function mytable_changes_trigger() returns trigger as $$
begin
if (tg_op = 'insert') then
insert into mytable_changes (block, hash)
values (new.block, hash);
return new;
if (tg_op = 'delete') then
insert into mytable_changes (block, hash)
values (old.block, old.hash);
return old;
elsif (tg_op = 'update') then
insert into mytable_changes (block, hash)
values (old.block, old.hash);
return new;
end if;
end;
$$ language plpgsql;
And create this trigger: create trigger mytable_changes
after insert, update or delete on mytable
for each row
execute function mytable_changes_trigger();
What's left as an exercise is that the hash of the prev. block is being preprended.Here is a correct (OPs is slightly but importantly wrong) and shorter one in JavaScript:
const crypto = require('crypto');
function Block(index, data, prevHash) {
this.index = index;
this.data = data;
this.prevHash = prevHash;
this.hash = crypto.createHash('sha256').update(`${this.index}${this.data}${this.prevHash}`).digest('hex');
}
function Blockchain() {
this.chain = [new Block(0, 'Genesis', '0')];
}
Blockchain.prototype.add = function(data) {
const prevBlock = this.chain[this.chain.length - 1];
this.chain.push(new Block(prevBlock.index + 1, data, prevBlock.hash));
};
Any ways we can make it even shorter? const crypto = require('crypto')
const Block = (index, data, prevHash) => ({
index,
data,
prevHash,
hash: crypto.createHash('sha256').update(index + data + prevHash).digest('hex'),
})
const Blockchain = () => ({
chain: [Block(0, 'Genesis', '0')],
add(data) {
return this.chain.push(
Block(this.chain.at(-1).index + 1, data, this.chain.at(-1).hash)
)
},
})
The data that’s hashed doesn’t include the hash from the previous block, so the chain can be tampered with by modifying only blocks n and n+1.