{"id":41940845,"url":"https://github.com/playmint/eth-carbon","last_synced_at":"2026-01-25T18:37:35.241Z","repository":{"id":57700267,"uuid":"462297823","full_name":"playmint/eth-carbon","owner":"playmint","description":"Estimate the CO2 emissions that Ethereum smart contracts are responsible for","archived":false,"fork":false,"pushed_at":"2022-06-17T12:45:28.000Z","size":162,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-05T15:15:16.868Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc0-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/playmint.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-02-22T12:56:25.000Z","updated_at":"2025-01-05T09:25:38.000Z","dependencies_parsed_at":"2022-09-26T21:10:48.111Z","dependency_job_id":null,"html_url":"https://github.com/playmint/eth-carbon","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/playmint/eth-carbon","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/playmint%2Feth-carbon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/playmint%2Feth-carbon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/playmint%2Feth-carbon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/playmint%2Feth-carbon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/playmint","download_url":"https://codeload.github.com/playmint/eth-carbon/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/playmint%2Feth-carbon/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28756442,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-25T16:32:25.380Z","status":"ssl_error","status_checked_at":"2026-01-25T16:32:09.189Z","response_time":113,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-25T18:37:35.172Z","updated_at":"2026-01-25T18:37:35.234Z","avatar_url":"https://github.com/playmint.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# eth-carbon\n[![NPM Package](https://img.shields.io/npm/v/@playmint/eth-carbon.svg?style=flat-square)](https://www.npmjs.com/package/@playmint/eth-carbon)\nSmall library to estimate the CO2 emissions that Ethereum smart contracts are responsible for.\n\n## Installation\n`npm install @playmint/eth-carbon`\n\n## API\n```ts\nasync function estimateCO2(etherscanApiKey: string, contracts: ContractFilter[]): Promise\u003cEmissionsReport\u003e\n\ntype EmissionsEstimate = {\n    txCount: number;// number of transactions\n    gas: bigint;    // amount of gas used for calculation\n    lower: number;  // lower bound\n    best: number;   // best guess\n    upper: number;  // upper bound\n};\n\ntype EmissionsReport = {\n    total: EmissionsEstimate;\n    byAddress: { [address: string]: EmissionsReportForAddress };\n    byDate: { [date: string]: EmissionsEstimate };\n};\n\ntype EmissionsReportForAddress = {\n    total: EmissionsEstimate;\n    byDate: { [date: string]: EmissionsReportForAddressAndDate };\n    bySelector: { [selector: string]: EmissionsEstimate };\n};\n\ntype EmissionsReportForAddressAndDate = {\n    total: EmissionsEstimate;\n    bySelector: { [selector: string]: EmissionsEstimate };\n};\n\ntype ContractFilter = {\n    // contract address\n    address: string;\n    // include the contract creation transaction, defaults to true\n    shouldIncludeContractCreation?: boolean;\n    // include failed transactions, default is false\n    shouldIncludeFailedTransactions?: boolean;\n    // 4 byte function selectors to include, if both 'selectors' and 'functions' \n    // are undefined, then all transactions will be included\n    selectors?: Set\u003cstring\u003e;\n    // can include either function names or signatures, or both. If any function\n    // names are specified then the signature will be looked up from the ABI. If\n    // multiple functions have the same name then this will fail.\n    functions?: Set\u003cstring\u003e;\n    // this is only required if any functions are specified just as a function name\n    // and not the full function signature. If an ABI is needed but none is given,\n    // then an attempt will be made to get the ABI from etherscan, if the contract\n    // isn't verified on etherscan then this step will fail. This can be a json\n    // string, or an array of objects fitting the ABIFunction type (e.g.\n    // ethers.utils.Interface.fragments). This is also used if selectors are\n    // specified in the filter rather than the function name, the report will\n    // attempt to display the function name in the report along with the selector\n    // to make it more readable, however if an abi can't be found then it will\n    // still produce the report using just the selectors.\n    abi?: string | readonly ABIFunction[];\n    // used to convert a selector to a function name, if omitted then it will be\n    // automatically generated from the abi\n    selectorToFunction?: { [selector: string]: string };\n};\n\ntype ABIField = {\n\tname: string;\n\ttype: string;\n\tcomponents?: ABIField[];\n};\n\ntype ABIFunction = {\n\ttype: \"function\" | \"constructor\" | \"receive\" | \"fallback\";\n\tname: string;\n\tinputs: ABIField[];\n\toutputs?: ABIField[];\n\tstateMutability: \"pure\" | \"view\" | \"payable\" | \"nonpayable\";\n};\n\nasync function getTransactionsForContracts(apiKey: string, contracts: ContractFilter[]): Promise\u003c{[address: string]: Transaction[]}\u003e\n\ntype Transaction = {\n\tblockNumber: number;\n\ttimeStamp: number;\n\tinput: string;\n\tgasUsed: number;\n\tisError: boolean;\n\tselector: string;\n\tisContractCreation: boolean;\n};\n```\n\n## Examples\nStandard emissions report\n```ts\nimport {estimateCO2} from \"@playmint/eth-carbon\";\n\nasync function main() {\n    const contracts = [{address: \"\u003ccontractAddress1\u003e\"}, {address: \"\u003ccontractAddress2\u003e\"}];\n\tconst emissionsReport = await estimateCO2(\"\u003cetherscan API key\u003e\", contracts);\n\n    console.log(reportToString(report, contracts));\n}\n\nmain().catch((e) =\u003e {\n\tconsole.error(e);\n}\n```\nFiltering by functions and selectors\n```ts\nconst emissionsReport = await estimateCO2(\n\t\"\u003cetherscan API key\u003e\", [{\n\t\taddress: \"\u003ccontractAddress\u003e\",\n\t\tselectors: new Set\u003cstring\u003e([\"12345678\", \"9abcdef0\"]),\n\t\tfunctions: new Set\u003cstring\u003e([\"func1\", \"func2\", \"func3(uint256,string)\"])\n\t}]);\n```\nPassing ABI from EthersJS object\n```ts\nlet contract = new ethers.Contract(...);\nconst emissionsReport = await estimateCO2(\n\t\"\u003cetherscan api key\u003e\", [{\n\t\taddress:\"\u003ccontractAddress\u003e\",\n\t\tfunctions:  new  Set\u003cstring\u003e([\"func1\", \"func2\"]),\n\t\tabi:  contract.interface.fragments  as  unknown  as  ABIFunction[]\n\t}]);\n```\nExample EmissionsReport object\n```json\n{\n    \"total\": {\n        \"txCount\": 9,\n        \"gas\": \"4314765\",\n        \"lower\": 0.6446255524183231,\n        \"best\": 0.905229230287158,\n        \"upper\": 1.2960386267870376\n    },\n    \"byAddress\": {\n        \"0x38065291fDce1A752afD725e96FF75E1c38aD6aa\": {\n            \"total\": {\n                \"txCount\": 6,\n                \"gas\": \"817602\",\n                \"lower\": 0.11491131630982421,\n                \"best\": 0.1639256825215661,\n                \"upper\": 0.23690653735634648\n            },\n            \"byDate\": {\n                \"2022-01-27T00:00:00.000Z\": {\n                    \"total\": {\n                        \"txCount\": 3,\n                        \"gas\": \"655833\",\n                        \"lower\": 0.09163122585960128,\n                        \"best\": 0.13090175122800182,\n                        \"upper\": 0.18980753928060262\n                    },\n                    \"bySelector\": {\n                        \"60806040\": {\n                            \"txCount\": 1,\n                            \"gas\": \"135596\",\n                            \"lower\": 0.01894510904705694,\n                            \"best\": 0.02706444149579563,\n                            \"upper\": 0.03924344016890366\n                        },\n                        \"1acbd301\": {\n                            \"txCount\": 1,\n                            \"gas\": \"466310\",\n                            \"lower\": 0.06515158116561788,\n                            \"best\": 0.09307368737945411,\n                            \"upper\": 0.13495684670020847\n                        },\n                        \"168a35fa\": {\n                            \"txCount\": 1,\n                            \"gas\": \"53927\",\n                            \"lower\": 0.0075345356469264544,\n                            \"best\": 0.010763622352752078,\n                            \"upper\": 0.015607252411490514\n                        },\n                        \"contractCreation\": {\n                            \"txCount\": 1,\n                            \"gas\": \"135596\",\n                            \"lower\": 0.01894510904705694,\n                            \"best\": 0.02706444149579563,\n                            \"upper\": 0.03924344016890366\n                        },\n                        \"init(string,string,address,string,string,string,string,string,string,uint256,address)\": {\n                            \"txCount\": 1,\n                            \"gas\": \"466310\",\n                            \"lower\": 0.06515158116561788,\n                            \"best\": 0.09307368737945411,\n                            \"upper\": 0.13495684670020847\n                        },\n                        \"addWhitelistedMinter(address)\": {\n                            \"txCount\": 1,\n                            \"gas\": \"53927\",\n                            \"lower\": 0.0075345356469264544,\n                            \"best\": 0.010763622352752078,\n                            \"upper\": 0.015607252411490514\n                        }\n                    }\n                },\n                \"2022-02-09T00:00:00.000Z\": {\n                    \"total\": {\n                        \"txCount\": 1,\n                        \"gas\": \"53915\",\n                        \"lower\": 0.007543440454171489,\n                        \"best\": 0.01077634350595927,\n                        \"upper\": 0.015625698083640942\n                    },\n                    \"bySelector\": {\n                        \"168a35fa\": {\n                            \"txCount\": 1,\n                            \"gas\": \"53915\",\n                            \"lower\": 0.007543440454171489,\n                            \"best\": 0.01077634350595927,\n                            \"upper\": 0.015625698083640942\n                        },\n                        \"addWhitelistedMinter(address)\": {\n                            \"txCount\": 1,\n                            \"gas\": \"53915\",\n                            \"lower\": 0.007543440454171489,\n                            \"best\": 0.01077634350595927,\n                            \"upper\": 0.015625698083640942\n                        }\n                    }\n                },\n                \"2022-03-03T00:00:00.000Z\": {\n                    \"total\": {\n                        \"txCount\": 1,\n                        \"gas\": \"53927\",\n                        \"lower\": 0.007569722759654204,\n                        \"best\": 0.010813889656648864,\n                        \"upper\": 0.015139445519308408\n                    },\n                    \"bySelector\": {\n                        \"168a35fa\": {\n                            \"txCount\": 1,\n                            \"gas\": \"53927\",\n                            \"lower\": 0.007569722759654204,\n                            \"best\": 0.010813889656648864,\n                            \"upper\": 0.015139445519308408\n                        },\n                        \"addWhitelistedMinter(address)\": {\n                            \"txCount\": 1,\n                            \"gas\": \"53927\",\n                            \"lower\": 0.007569722759654204,\n                            \"best\": 0.010813889656648864,\n                            \"upper\": 0.015139445519308408\n                        }\n                    }\n                },\n                \"2022-04-14T00:00:00.000Z\": {\n                    \"total\": {\n                        \"txCount\": 1,\n                        \"gas\": \"53927\",\n                        \"lower\": 0.008166927236397246,\n                        \"best\": 0.011433698130956144,\n                        \"upper\": 0.016333854472794493\n                    },\n                    \"bySelector\": {\n                        \"168a35fa\": {\n                            \"txCount\": 1,\n                            \"gas\": \"53927\",\n                            \"lower\": 0.008166927236397246,\n                            \"best\": 0.011433698130956144,\n                            \"upper\": 0.016333854472794493\n                        },\n                        \"addWhitelistedMinter(address)\": {\n                            \"txCount\": 1,\n                            \"gas\": \"53927\",\n                            \"lower\": 0.008166927236397246,\n                            \"best\": 0.011433698130956144,\n                            \"upper\": 0.016333854472794493\n                        }\n                    }\n                }\n            },\n            \"bySelector\": {\n                \"60806040\": {\n                    \"txCount\": 1,\n                    \"gas\": \"135596\",\n                    \"lower\": 0.01894510904705694,\n                    \"best\": 0.02706444149579563,\n                    \"upper\": 0.03924344016890366\n                },\n                \"1acbd301\": {\n                    \"txCount\": 1,\n                    \"gas\": \"466310\",\n                    \"lower\": 0.06515158116561788,\n                    \"best\": 0.09307368737945411,\n                    \"upper\": 0.13495684670020847\n                },\n                \"168a35fa\": {\n                    \"txCount\": 4,\n                    \"gas\": \"215696\",\n                    \"lower\": 0.030814626097149394,\n                    \"best\": 0.043787553646316354,\n                    \"upper\": 0.06270625048723436\n                },\n                \"contractCreation\": {\n                    \"txCount\": 1,\n                    \"gas\": \"135596\",\n                    \"lower\": 0.01894510904705694,\n                    \"best\": 0.02706444149579563,\n                    \"upper\": 0.03924344016890366\n                },\n                \"init(string,string,address,string,string,string,string,string,string,uint256,address)\": {\n                    \"txCount\": 1,\n                    \"gas\": \"466310\",\n                    \"lower\": 0.06515158116561788,\n                    \"best\": 0.09307368737945411,\n                    \"upper\": 0.13495684670020847\n                },\n                \"addWhitelistedMinter(address)\": {\n                    \"txCount\": 4,\n                    \"gas\": \"215696\",\n                    \"lower\": 0.030814626097149394,\n                    \"best\": 0.043787553646316354,\n                    \"upper\": 0.06270625048723436\n                }\n            }\n        },\n        \"0xe3c37f80077689f660Cd63BD48D81C746dF51363\": {\n            \"total\": {\n                \"txCount\": 3,\n                \"gas\": \"3497163\",\n                \"lower\": 0.5297142361084989,\n                \"best\": 0.7413035477655918,\n                \"upper\": 1.0591320894306913\n            },\n            \"byDate\": {\n                \"2022-04-14T00:00:00.000Z\": {\n                    \"total\": {\n                        \"txCount\": 2,\n                        \"gas\": \"3468398\",\n                        \"lower\": 0.525268494313901,\n                        \"best\": 0.7353758920394613,\n                        \"upper\": 1.050536988627802\n                    },\n                    \"bySelector\": {\n                        \"61028060\": {\n                            \"txCount\": 1,\n                            \"gas\": \"3422023\",\n                            \"lower\": 0.518245273096553,\n                            \"best\": 0.7255433823351742,\n                            \"upper\": 1.036490546193106\n                        },\n                        \"399dde76\": {\n                            \"txCount\": 1,\n                            \"gas\": \"46375\",\n                            \"lower\": 0.007023221217347939,\n                            \"best\": 0.009832509704287114,\n                            \"upper\": 0.014046442434695878\n                        },\n                        \"contractCreation\": {\n                            \"txCount\": 1,\n                            \"gas\": \"3422023\",\n                            \"lower\": 0.518245273096553,\n                            \"best\": 0.7255433823351742,\n                            \"upper\": 1.036490546193106\n                        },\n                        \"setRelayAddress(address,bool)\": {\n                            \"txCount\": 1,\n                            \"gas\": \"46375\",\n                            \"lower\": 0.007023221217347939,\n                            \"best\": 0.009832509704287114,\n                            \"upper\": 0.014046442434695878\n                        }\n                    }\n                },\n                \"2022-04-21T00:00:00.000Z\": {\n                    \"total\": {\n                        \"txCount\": 1,\n                        \"gas\": \"28765\",\n                        \"lower\": 0.0044457417945978715,\n                        \"best\": 0.0059276557261304956,\n                        \"upper\": 0.008595100802889218\n                    },\n                    \"bySelector\": {\n                        \"d8db091e\": {\n                            \"txCount\": 1,\n                            \"gas\": \"28765\",\n                            \"lower\": 0.0044457417945978715,\n                            \"best\": 0.0059276557261304956,\n                            \"upper\": 0.008595100802889218\n                        },\n                        \"enableXpRewards(bool)\": {\n                            \"txCount\": 1,\n                            \"gas\": \"28765\",\n                            \"lower\": 0.0044457417945978715,\n                            \"best\": 0.0059276557261304956,\n                            \"upper\": 0.008595100802889218\n                        }\n                    }\n                }\n            },\n            \"bySelector\": {\n                \"61028060\": {\n                    \"txCount\": 1,\n                    \"gas\": \"3422023\",\n                    \"lower\": 0.518245273096553,\n                    \"best\": 0.7255433823351742,\n                    \"upper\": 1.036490546193106\n                },\n                \"399dde76\": {\n                    \"txCount\": 1,\n                    \"gas\": \"46375\",\n                    \"lower\": 0.007023221217347939,\n                    \"best\": 0.009832509704287114,\n                    \"upper\": 0.014046442434695878\n                },\n                \"d8db091e\": {\n                    \"txCount\": 1,\n                    \"gas\": \"28765\",\n                    \"lower\": 0.0044457417945978715,\n                    \"best\": 0.0059276557261304956,\n                    \"upper\": 0.008595100802889218\n                },\n                \"contractCreation\": {\n                    \"txCount\": 1,\n                    \"gas\": \"3422023\",\n                    \"lower\": 0.518245273096553,\n                    \"best\": 0.7255433823351742,\n                    \"upper\": 1.036490546193106\n                },\n                \"setRelayAddress(address,bool)\": {\n                    \"txCount\": 1,\n                    \"gas\": \"46375\",\n                    \"lower\": 0.007023221217347939,\n                    \"best\": 0.009832509704287114,\n                    \"upper\": 0.014046442434695878\n                },\n                \"enableXpRewards(bool)\": {\n                    \"txCount\": 1,\n                    \"gas\": \"28765\",\n                    \"lower\": 0.0044457417945978715,\n                    \"best\": 0.0059276557261304956,\n                    \"upper\": 0.008595100802889218\n                }\n            }\n        }\n    },\n    \"byDate\": {\n        \"2022-01-27T00:00:00.000Z\": {\n            \"txCount\": 3,\n            \"gas\": \"655833\",\n            \"lower\": 0.09163122585960128,\n            \"best\": 0.13090175122800182,\n            \"upper\": 0.18980753928060262\n        },\n        \"2022-02-09T00:00:00.000Z\": {\n            \"txCount\": 1,\n            \"gas\": \"53915\",\n            \"lower\": 0.007543440454171489,\n            \"best\": 0.01077634350595927,\n            \"upper\": 0.015625698083640942\n        },\n        \"2022-03-03T00:00:00.000Z\": {\n            \"txCount\": 1,\n            \"gas\": \"53927\",\n            \"lower\": 0.007569722759654204,\n            \"best\": 0.010813889656648864,\n            \"upper\": 0.015139445519308408\n        },\n        \"2022-04-14T00:00:00.000Z\": {\n            \"txCount\": 3,\n            \"gas\": \"3522325\",\n            \"lower\": 0.5334354215502982,\n            \"best\": 0.7468095901704175,\n            \"upper\": 1.0668708431005964\n        },\n        \"2022-04-21T00:00:00.000Z\": {\n            \"txCount\": 1,\n            \"gas\": \"28765\",\n            \"lower\": 0.0044457417945978715,\n            \"best\": 0.0059276557261304956,\n            \"upper\": 0.008595100802889218\n        }\n    }\n}\n```\n## How it works\nContract transactions are divided into days, and their combined gas cost per day is calculated. Using daily network gas usage data from [https://etherscan.io/chart/gasused](https://etherscan.io/chart/gasused) it calculates the percentage of the daily gas used by the contract. Then using daily CO2 emissions estimates from [https://kylemcdonald.github.io/ethereum-emissions/](https://kylemcdonald.github.io/ethereum-emissions/) it uses the daily gas percentage to estimate emissions for that day. All of the emissions figures across all days can then be added together for a final total figure.  ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplaymint%2Feth-carbon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fplaymint%2Feth-carbon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplaymint%2Feth-carbon/lists"}