{"id":26313902,"url":"https://github.com/opentimestamps/java-opentimestamps","last_synced_at":"2025-05-13T01:34:23.348Z","repository":{"id":46809655,"uuid":"83357738","full_name":"opentimestamps/java-opentimestamps","owner":"opentimestamps","description":null,"archived":false,"fork":false,"pushed_at":"2024-07-19T05:18:59.000Z","size":690,"stargazers_count":42,"open_issues_count":9,"forks_count":32,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-05-06T21:13:40.291Z","etag":null,"topics":["bitcoin-attestation","cryptography","java","opentimestamps"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/opentimestamps.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-02-27T21:16:21.000Z","updated_at":"2025-01-04T08:18:56.000Z","dependencies_parsed_at":"2022-07-26T13:17:07.651Z","dependency_job_id":null,"html_url":"https://github.com/opentimestamps/java-opentimestamps","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opentimestamps%2Fjava-opentimestamps","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opentimestamps%2Fjava-opentimestamps/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opentimestamps%2Fjava-opentimestamps/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opentimestamps%2Fjava-opentimestamps/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/opentimestamps","download_url":"https://codeload.github.com/opentimestamps/java-opentimestamps/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253854531,"owners_count":21974307,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["bitcoin-attestation","cryptography","java","opentimestamps"],"created_at":"2025-03-15T11:17:20.959Z","updated_at":"2025-05-13T01:34:23.329Z","avatar_url":"https://github.com/opentimestamps.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# java-opentimestamps\n\n[![OpenTimestamps logo][2]][1]\n\n[1]: https://opentimestamps.org\n[2]: https://raw.githubusercontent.com/opentimestamps/logo/master/white-bg/website-horizontal-350x75.png (OpenTimestamps logo)\n\n[![Build Status](https://travis-ci.org/opentimestamps/java-opentimestamps.svg?branch=master)](https://travis-ci.org/opentimestamps/java-opentimestamps)\n\nThis repo host the Java implementation of OpenTimestamps.\n\nIt is a based on the python implementation at https://github.com/opentimestamps/python-opentimestamps and https://github.com/opentimestamps/opentimestamps-client\n\n## Compatibility\n\nJava 1.7+\n\n## Maven dependency\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.eternitywall\u003c/groupId\u003e\n    \u003cartifactId\u003ejava-opentimestamps\u003c/artifactId\u003e\n    \u003cversion\u003e1.20\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## Installation\n\n```\ngit clone https://github.com/opentimestamps/java-opentimestamps\ncd java-opentimestamps\nmvn install\n```\n\n#### SSL errors\n\nIf you get `SSLHandshakeException` during `mvn install` please refer to the following [issue](https://github.com/opentimestamps/java-opentimestamps/issues/1).\n\n## Command line\n\n#### Stamp\n\nCreate timestamp `README.md.ots` from this `README.md` with the aid of a remote calendar.\n\n```shell\n$ java -jar target/OtsCli.jar stamp README.md\nSubmitting to remote calendar https://alice.btc.calendar.opentimestamps.org\nSubmitting to remote calendar https://bob.btc.calendar.opentimestamps.org\nSubmitting to remote calendar https://finney.calendar.eternitywall.com\nThe timestamp proof 'README.md.ots' has been created!\n```\n\n##### Stamping only a hash\n\nCreate timestamp proof file from the `sha256` hash, equals to `03ba204e50d126e4674c005e04d82e84c21366780af1f43bd54a37816b6ab340`, with the aid of a remote calendar.\n\n ```shell\n$ java -jar target/OtsCli.jar -H 03ba204e50d126e4674c005e04d82e84c21366780af1f43bd54a37816b6ab340 -a sha256 stamp\nINFO: Submitting to remote calendar https://alice.btc.calendar.opentimestamps.org\nINFO: Submitting to remote calendar https://bob.btc.calendar.opentimestamps.org\nINFO: Submitting to remote calendar https://finney.calendar.eternitywall.com\nThe timestamp proof '03ba204e50d126e4674c005e04d82e84c21366780af1f43bd54a37816b6ab340.ots' has been created!\n```\n\n#### Info\n\nShow information on a timestamp.\n\n```shell\n$ java -jar target/OtsCli.jar info examples/incomplete.txt.ots\nFile sha256 hash: 05c4f616a8e5310d19d938cfd769864d7f4ccdc2ca8b479b10af83564b097af9\nTimestamp:\nappend e754bf93806a7ebaa680ef7bd0114bf4\nsha256\nappend b573e8850cfd9e63d1f043fbb6fc250e\nsha256\nprepend 57cfa5c4\nappend 6fb1ac8d4e4eb0e7\nverify PendingAttestation('https://alice.btc.calendar.opentimestamps.org')\n\n```\n\n#### Verify\n\nVerify the timestamp attestations with the aid of remote block explorers.\n\n```shell\n$ java -jar target/OtsCli.jar verify examples/hello-world.txt.ots\nAssuming target filename is 'examples/hello-world.txt'\nSuccess! Bitcoin attests data existed as of Thu May 28 2015 17:41:18 GMT+0200 (CEST)\n```\n\nNote: This verification using block explorers is convenient but not as secure as asking to a local node.\nTo mitigate the risks, answer from block explorer is considered only if two different endpoint return the same result. Even by doing so this is not as secure as asking a local node.   \n\n#### Upgrade\n\nUpgrade incomplete remote calendar timestamps to be independently verifiable. This command overwrite the file `examples/incomplete.txt.ots` if needed and make a backup of the old content at `examples/incomplete.txt.ots`.\n\n```shell\n$ java -jar target/OtsCli.jar upgrade examples/incomplete.txt.ots\nTimestamp has been successfully upgraded!\n```\n\n##### Shrink\n\nWhen a proof is completed with at least one bitcoin attestation, information regarding other paths are redundant.\nThe oldest bitcoin attestation (the lower bitcoin block height) is the only relevant information, in this case we can shrink all the redundant informatio.\n\n```shell\n$ java -jar target/OtsCli.jar upgrade examples/merkle2.txt.ots \nTimestamp has been successfully upgraded!\n$ java -jar target/OtsCli.jar info examples/merkle2.txt.ots\n# ... have a look at the double path\n$ java -jar target/OtsCli.jar upgrade examples/merkle2.txt.ots\n$ java -jar target/OtsCli.jar info examples/merkle2.txt.ots\n# ... now the ots receipt contains only the relevant information\n\n```\n\n## From code\n\n#### Stamp and Info\n\nCreate timestamp with the aid of remote calendars.\n\n```java\nDetachedTimestampFile detached = DetachedTimestampFile.from(new OpSHA256(), file);\nTimestamp stampResult = OpenTimestamps.stamp(detached);\nString infoResult = OpenTimestamps.info(detached);\nSystem.out.println(infoResult);\n```\n\n#### Verify\n\nVerify the timestamp attestations.\n\n```java\nbyte[] file = Utils.hexToBytes(\"48656c6c6f20576f726c64210a\");\nbyte[] fileOts = Utils.hexToBytes(\"004f70656e54696d657374616d7073000050726f6f6600bf89e2e884e89294010803ba204e50d126e4674c005e04d82e84c21366780af1f43bd54a37816b6ab34003f1c8010100000001e482f9d32ecc3ba657b69d898010857b54457a90497982ff56f97c4ec58e6f98010000006b483045022100b253add1d1cf90844338a475a04ff13fc9e7bd242b07762dea07f5608b2de367022000b268ca9c3342b3769cdd062891317cdcef87aac310b6855e9d93898ebbe8ec0121020d8e4d107d2b339b0050efdd4b4a09245aa056048f125396374ea6a2ab0709c6ffffffff026533e605000000001976a9140bf057d40fbba6744862515f5b55a2310de5772f88aca0860100000000001976a914f00688ac000000000808f120a987f716c533913c314c78e35d35884cac943fa42cac49d2b2c69f4003f85f880808f120dec55b3487e1e3f722a49b55a7783215862785f4a3acb392846019f71dc64a9d0808f120b2ca18f485e080478e025dab3d464b416c0e1ecb6629c9aefce8c8214d0424320808f02011b0e90661196ff4b0813c3eda141bab5e91604837bdf7a0c9df37db0e3a11980808f020c34bc1a4a1093ffd148c016b1e664742914e939efabe4d3d356515914b26d9e20808f020c3e6e7c38c69f6af24c2be34ebac48257ede61ec0a21b9535e4443277be306460808f1200798bf8606e00024e5d5d54bf0c960f629dfb9dad69157455b6f2652c0e8de810808f0203f9ada6d60baa244006bb0aad51448ad2fafb9d4b6487a0999cff26b91f0f5360808f120c703019e959a8dd3faef7489bb328ba485574758e7091f01464eb65872c975c80808f020cbfefff513ff84b915e3fed6f9d799676630f8364ea2a6c7557fad94a5b5d7880808f1200be23709859913babd4460bbddf8ed213e7c8773a4b1face30f8acfdf093b7050808000588960d73d7190103f7ef15\");\n\nDetachedTimestampFile detached = DetachedTimestampFile.from(new OpSHA256(), file);\nDetachedTimestampFile detachedOts = DetachedTimestampFile.deserialize(fileOts);\n\nHashMap\u003cVerifyResult.Chains, VerifyResult\u003e result = OpenTimestamps.verify(detachedOts,detached);\nif (result == null || result.isEmpty()) {\n    System.out.println(\"Pending or Bad attestation\");\n} else {\n    result.forEach((k, v) -\u003e System.out.println(\"Success! \" + k + \" attests data existed as of \"+ new Date(v.timestamp * 1000)));\n}\n```\n\nVariable `fileOts` created from the hex representation of the file `test/hello-world.txt.ots` while `file` contains `test/hello-world.txt`\n\n#### Upgrade\n\nUpgrade incomplete remote calendar timestamps to be indipendently verifiable.\n\n```java\nbyte[] ots = Utils.hexToBytes(\"004f70656e54696d657374616d7073000050726f6f6600bf89e2e884e89294010805c4f616a8e5310d19d938cfd769864d7f4ccdc2ca8b479b10af83564b097af9f010e754bf93806a7ebaa680ef7bd0114bf408f010b573e8850cfd9e63d1f043fbb6fc250e08f10457cfa5c4f0086fb1ac8d4e4eb0e70083dfe30d2ef90c8e2e2d68747470733a2f2f616c6963652e6274632e63616c656e6461722e6f70656e74696d657374616d70732e6f7267\");\nDetachedTimestampFile detachedOts = DetachedTimestampFile.deserialize(ots);\nboolean changed = OpenTimestamps.upgrade(detachedOts);\nif(!changed) {\n   System.out.println(\"Timestamp not upgraded\");\n} else {\n   System.out.println(\"Timestamp upgraded\");\n}\n```\n\n## Testing\n\n```\ncd java-opentimestamps\nmvn test\n```\n\n\n\n## License\n\nLGPL3\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopentimestamps%2Fjava-opentimestamps","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopentimestamps%2Fjava-opentimestamps","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopentimestamps%2Fjava-opentimestamps/lists"}