-
Notifications
You must be signed in to change notification settings - Fork 839
Add Real-World Util Blob Example #4192
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
That blob works at Copy-past from website to file:This is with '0x' (262146 bytes). Code works with both. # sha256 blob.txt
SHA256 (blob.txt) = b5cf2485712c37a318dc771f4ec8e20ea75a4e3d7607b3f23e2c7e2c3bb2e08dThis hash of version without '0x' (262144 bytes): SHA256 (blob.txt) = e320325cdac9a57057e3e8902c6b71d0131afa2ac4ae140f1c238d364cafe5dbOld version: "node_modules/micro-eth-signer": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/micro-eth-signer/-/micro-eth-signer-0.15.0.tgz",
"integrity": "sha512-VkKK698Odm0ef40ERC9FdcG6BHBL9vWhy+7xkLL1M0O3bcRBLi7FP7mr+4SdiPaP823Q+r6c8JdUtWdESSf06A==",
"license": "MIT",
"dependencies": {
"@noble/curves": "~1.9.1",
"@noble/hashes": "~1.8.0",
"micro-packed": "~0.7.3"
}
},// "micro-eth-signer": "^0.15.0"
import * as fs from 'node:fs';
import { KZG } from 'micro-eth-signer/kzg.js';
import { trustedSetup as s_fast } from '@paulmillr/trusted-setups/fast-kzg.js';
import { deepStrictEqual } from 'node:assert';
const kzg = new KZG(s_fast);
const blob = fs.readFileSync('./blob.txt', 'utf8');
/*
OK [
9950896364063828479760105497824655790015207806091689101821226327781578341321n,
5073668346629795774871283667712309276490414982699714158417373496810743118145n,
25176228008882631450863129405107679141280536219895767651782763491732366126953n,
2611873799884172396458779361450711640617140137603788323278223043506227032276n,
27008833669916875399255315324821569880893552449183082959694602115932697760336n,
22338810404566275086580161916721569668795387632298891059325211760519627059809n,
23774835051371149139915222215553252928398022756962564187347204236001807219301n,
16508100157248019383180095226
*/
console.log('OK', kzg.parseBlob(blob));
// passes!
deepStrictEqual(
kzg.verifyBlobProof(
blob,
'0x873889d4a2ebc9b85b6e644f00475e74fe9123c930dd57002621952e4d8f2fff7329b78eb51d08746280939f5c45f611',
'0x8397af82a8aca743b2bd3041ec76b467783de03903ee704403de4a41a28ce6c1e2fb66b195c0a0151b6285ad523e6fc8'
),
true
);New version// "micro-eth-signer": "^0.17.3"
import * as fs from 'node:fs';
import { KZG } from 'micro-eth-signer/advanced/kzg.js';
import { trustedSetup as s_fast } from '@paulmillr/trusted-setups/fast-kzg.js';
import { deepStrictEqual } from 'node:assert';
const kzg = new KZG(s_fast);
const blob = fs.readFileSync('./blob.txt', 'utf8');
console.log('OK', kzg.parseBlob(blob));
deepStrictEqual(
kzg.verifyBlobProof(
blob,
'0x873889d4a2ebc9b85b6e644f00475e74fe9123c930dd57002621952e4d8f2fff7329b78eb51d08746280939f5c45f611',
'0x8397af82a8aca743b2bd3041ec76b467783de03903ee704403de4a41a28ce6c1e2fb66b195c0a0151b6285ad523e6fc8'
),
true
);ExampleSeems like an issue with code in the example: export function getBlob(data: Uint8Array): PrefixedHexString {
const blob = new Uint8Array(BLOB_SIZE);
for (let i = 0; i < FIELD_ELEMENTS_PER_BLOB; i++) {
const chunk = new Uint8Array(32);
chunk.set(data.subarray(i * 31, (i + 1) * 31), 0);
blob.set(chunk, i * 32);
}
return bytesToHex(blob);
}This is incorrect: Working example code: import * as fs from 'fs';
import {
type PrefixedHexString,
blobsToCellProofs,
blobsToProofs,
computeVersionedHash,
hexToBytes,
bytesToHex,
} from '@ethereumjs/util';
import { trustedSetup } from '@paulmillr/trusted-setups/fast-peerdas.js';
import { KZG as microEthKZG } from 'micro-eth-signer/kzg.js';
const BYTES_PER_FIELD_ELEMENT = 32; // EIP-4844
const FIELD_ELEMENTS_PER_BLOB = 4096; // EIP-4844
const BLOB_SIZE = BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_BLOB;
const MAX_BLOBS_PER_TX = 6; // EIP-7691: Blob throughput increase, Pectra HF
const MAX_BLOB_BYTES_PER_TX = BLOB_SIZE * MAX_BLOBS_PER_TX - 1;
export function getBlob(data: Uint8Array): PrefixedHexString {
const blob = new Uint8Array(BLOB_SIZE);
for (let i = 0; i < FIELD_ELEMENTS_PER_BLOB; i++) {
const chunk = new Uint8Array(32);
chunk.set(data.subarray(i * 32, (i + 1) * 32), 0);
blob.set(chunk, i * 32);
}
return bytesToHex(blob);
}
const kzg = new microEthKZG(trustedSetup);
// Use with node ./examples/blobs.ts <file path>
const filePath = process.argv[2];
let blobData: string = fs.readFileSync(filePath, 'ascii');
console.log(blobData);
console.log(blobData.length);
//blobData = blobData.substring(0, 100);
const blobs = [getBlob(hexToBytes(`0x${blobData}`))];
//const blobData = 'hello'
//const blobs = getBlobs(blobData)
console.log('Created the following blobs:');
//console.log(blobs)
const commitment = kzg.blobToKzgCommitment(blobs[0]);
const blobCommitmentVersion = 0x01;
const versionedHash = computeVersionedHash(commitment as PrefixedHexString, blobCommitmentVersion);
// EIP-4844 only
const blobProof = blobsToProofs(kzg, blobs, [commitment as PrefixedHexString]);
const cellProofs = blobsToCellProofs(kzg, blobs);
console.log(`Commitment : ${commitment}`);
console.log(`Versioned hash : ${versionedHash}`);
console.log(`Blob proof (EIP-4844) : ${blobProof}`);
console.log(`First cell proof (EIP-7594) : ${cellProofs[0]}`);
console.log(`Num cell proofs (EIP-7594) : ${cellProofs.length}`);That example outputs: Looks same as that website (versioned hash/proof/commitment same). |
|
Wow! 🤯 That works! I would have never expected that we (you!) find a bug in the production code with this real-world setup! But: that's great! Thanks so much! Need to clean this a bit up still, today too tired. Then we can also take this into the next releases. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
|
b603c27 to
9491036
Compare
|
To reiterate:
|
9491036 to
47dc3b0
Compare
e2871c2 to
e21a35b
Compare
|
Reverted the change to |
Hi @paulmillr maybe you can help with this one too, respectively I wonder if there is a blob-read bug still in
micro-eth-signer.So I am trying to do a real-world blob round trip, by downloading this blob from Blobscan (under the "Google" button) and then storing this as ascii hex with:
File with
vilooks solid and correct:I have then used the following code from this PR to read in this blob, respectively after first trying to read the full one I switched to read chunks of it (see the
substring(0, 100)in the example code).Doing this with
0, 32works:But going "full blob" or even going up to
0, 64breaks the thing with:/node_modules/micro-eth-signer/esm/kzg.js:39 throw new Error('parseScalar: invalid field element'); ^ Error: parseScalar: invalid field elementIs this really correct to go through
parseScalarhere? Shouldn't a blob just be arbitraty data?Note that I am testing on
micro-eth-signer15.0.0, the related logic doesn't seem to have changed though, checked in the code.