├── webank_blockchain_qrcode.png ├── docs ├── tutorials │ └── assets │ │ ├── 8-for.png │ │ ├── 10-array.png │ │ ├── 12-call2.png │ │ ├── 14-call1.png │ │ ├── 15-call3.png │ │ ├── 16-sig.png │ │ ├── 17-math.png │ │ ├── 18-call1.png │ │ ├── 19-call2.png │ │ ├── 2-remix.png │ │ ├── 20-proxy.png │ │ ├── 21-call3.png │ │ ├── 25-proxy.png │ │ ├── 26-proxy.png │ │ ├── 4-solc.png │ │ ├── 5-run-ev.png │ │ ├── 9-color.png │ │ ├── 1-evm-run.png │ │ ├── 12-account.png │ │ ├── 22-proxy2.png │ │ ├── 23-proxy3.png │ │ ├── 24-proxy4.png │ │ ├── 6-hello-1.png │ │ ├── 6-hello-2.png │ │ ├── 6-hello-3.png │ │ ├── 6-hello-4.png │ │ ├── 6-hello-5.png │ │ ├── 6-hello-6.png │ │ ├── 6-hello-7.png │ │ ├── 6-hello-8.png │ │ ├── 11-mapping-1.png │ │ ├── 13-mapping-2.png │ │ ├── 7-msg.sender.png │ │ ├── 3-file-browser.png │ │ └── 2-remix-complier.png ├── miscs │ └── tutorial │ │ └── assets │ │ ├── 8-for.png │ │ ├── 10-array.png │ │ ├── 2-remix.png │ │ ├── 4-solc.png │ │ ├── 5-run-ev.png │ │ ├── 9-color.png │ │ ├── 1-evm-run.png │ │ ├── 12-account.png │ │ ├── 6-hello-1.png │ │ ├── 6-hello-2.png │ │ ├── 6-hello-3.png │ │ ├── 6-hello-4.png │ │ ├── 6-hello-5.png │ │ ├── 6-hello-6.png │ │ ├── 6-hello-7.png │ │ ├── 6-hello-8.png │ │ ├── 11-mapping-1.png │ │ ├── 13-mapping-2.png │ │ ├── 7-msg.sender.png │ │ ├── 3-file-browser.png │ │ └── 2-remix-complier.png ├── business_template │ ├── CarbonFrugalEvidence.md │ ├── medicalCase │ │ ├── assets │ │ │ ├── 1.png │ │ │ ├── 2.png │ │ │ ├── 3.png │ │ │ ├── 4.png │ │ │ ├── 5.png │ │ │ ├── 6.png │ │ │ ├── 7.png │ │ │ ├── 8.png │ │ │ └── 9.png │ │ └── docCase.md │ ├── evidence_plus.md │ ├── SimplePoint.md │ ├── Traceability.md │ ├── Evidence.md │ ├── MarriageEvidence.md │ ├── HealthRecord.md │ └── RewardPoint.md ├── common_tools │ ├── counter.sol.md │ ├── FuncCallContract.md │ ├── LibBase64.md │ ├── MultiSign.md │ ├── CloneFactory.md │ ├── white_list_manage.md │ ├── RoleOperation.md │ ├── gm.md │ ├── Ballot.md │ ├── FiatShamirZK.md │ └── RBAC.md ├── base_type │ ├── Counters.md │ └── LibAscii.md ├── default │ ├── crypto │ │ ├── Crypto.md │ │ ├── LibDecode.md │ │ └── LibCryptoHash.md │ ├── internalFunction.md │ └── proxy │ │ └── proxy.md └── data_structure │ ├── DataTable.md │ ├── Map.md │ ├── LibMaxHeapUint256.md │ └── LibMinHeapUint256.md ├── contracts ├── default │ ├── proxy │ │ ├── ISing.sol │ │ ├── Sing.sol │ │ └── SingProxy.sol │ ├── HelloWorld.sol │ ├── crypto │ │ ├── Crypto.sol │ │ ├── ShaTest.sol │ │ ├── gm │ │ │ └── ICrypto.sol │ │ ├── LibCryptoHash.sol │ │ ├── LibDecode.sol │ │ ├── LibVerifySignature.sol │ │ └── VerifySignature.sol │ └── embeded_table │ │ └── KVTableTest.sol ├── common_tools │ ├── privacy_computation │ │ ├── Fiat-Shamir-ZK │ │ │ ├── contract_step2.py │ │ │ ├── contract_step45.py │ │ │ ├── contract_step1.py │ │ │ └── fiat_shamir_1.py │ │ └── DGHV-HE │ │ │ └── DGHV_Homomorphic_Encryption.sol │ ├── base64 │ │ └── LibBase64Test.sol │ ├── batch_execution_contract │ │ └── BatchExecutionTest.sol │ ├── role │ │ ├── RBAC │ │ │ ├── Roles.sol │ │ │ ├── Ownable.sol │ │ │ ├── Example.sol │ │ │ └── RBAC.sol │ │ ├── white_list │ │ │ ├── SafeRole.sol │ │ │ ├── WhitelistedRole.sol │ │ │ └── WhitelistAdminRole.sol │ │ └── role_operation │ │ │ └── Roles.sol │ ├── multi_call │ │ ├── MultiCall.sol │ │ └── MultiCallTest.sol │ ├── math │ │ ├── MathAdvanceTest.sol │ │ └── MathAdvance.sol │ ├── MultiSign │ │ └── MultiSignDemo.sol │ ├── func_call_contract │ │ └── FuncCallContract.sol │ ├── timelock │ │ ├── TimelockTest.sol │ │ ├── Ownable.sol │ │ └── SafeMath.sol │ ├── history-query │ │ └── HistoryQuery.sol │ ├── clone │ │ ├── CloneFactory.sol │ │ └── BallotFactory.sol │ ├── history_snapshot │ │ ├── HistorySnapshotV2Demo.sol │ │ └── HistorySnapshot.sol │ ├── proxy │ │ ├── MinimalProxy.sol │ │ └── MinimalProxyFactory.sol │ ├── counter │ │ └── SimpleCounter.sol │ └── counter.sol ├── business_template │ ├── Medicine │ │ ├── mocks │ │ │ ├── BasicTokenMock.sol │ │ │ ├── StandardTokenMock.sol │ │ │ └── SafeMathMock.sol │ │ ├── ERC20Basic.sol │ │ ├── ERC20.sol │ │ ├── Migrations.sol │ │ ├── SpringToken.sol │ │ ├── TokenDestructible.sol │ │ ├── Ownable.sol │ │ ├── SafeMath.sol │ │ └── BasicToken.sol │ ├── carbon_frugal_evidence │ │ ├── Address.sol │ │ ├── SafeMath.sol │ │ ├── EvidencesRepository.sol │ │ └── ECDSA.sol │ ├── divergence │ │ ├── IDivergence.sol │ │ └── LibGameCompare.sol │ ├── CharityFund │ │ ├── Roles.sol │ │ ├── SafeMath.sol │ │ └── CharityLogistics.sol │ ├── simple_point │ │ └── SimplePointDemo.sol │ ├── chattel │ │ ├── role │ │ │ └── Role.sol │ │ └── utils │ │ │ ├── Console.sol │ │ │ ├── Ownable.sol │ │ │ └── Table.sol │ ├── red_packet │ │ ├── IERC20.sol │ │ ├── proxy.sol │ │ └── SafeMath.sol │ ├── health_Record │ │ └── Auth.sol │ ├── bill │ │ └── utils │ │ │ ├── Console.sol │ │ │ ├── Ownable.sol │ │ │ └── Table.sol │ ├── reward_point │ │ ├── LibSafeMath.sol │ │ ├── BasicAuth.sol │ │ ├── LibRoles.sol │ │ ├── Admin.sol │ │ ├── IssuerRole.sol │ │ └── RewardPointData.sol │ ├── CarbonSystemManager │ │ ├── Ownable.sol │ │ └── SafeMath.sol │ ├── marriage_evidence │ │ ├── Roles.sol │ │ ├── MarriageEvidence.sol │ │ └── EvidenceFactory.sol │ ├── traceability │ │ ├── Goods.sol │ │ ├── Traceability.sol │ │ └── TraceabilityFactory.sol │ ├── evidence │ │ ├── Authentication.sol │ │ └── EvidenceRepository.sol │ ├── intellectualProperty │ │ └── sol │ │ │ ├── RoyaltyManager.sol │ │ │ ├── CopyrightManager.sol │ │ │ └── LicenseManager.sol │ ├── book_of_shares │ │ ├── interfaces │ │ │ └── IMembersRepository.sol │ │ └── lib │ │ │ └── LibArrayForAddressUtils.sol │ ├── gov_office │ │ └── lib │ │ │ └── Table.sol │ └── shared_bike │ │ └── UserStorage.sol ├── base_type │ ├── string │ │ └── StringDemo.sol │ ├── array │ │ ├── ArrayDemo.sol │ │ └── TwoDArrayDemo.sol │ ├── Counters.sol │ ├── LibAsciiDemo.sol │ ├── BasicDemo.sol │ └── bits │ │ └── TestBits.sol └── data_structure │ ├── map │ └── LibBytesMapDemo.sol │ ├── set │ └── AddressSetDemo.sol │ ├── LibStack.sol │ ├── LibQueue.sol │ └── table │ ├── DataTable.sol │ └── Map.sol ├── .gitignore └── README.md /webank_blockchain_qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/webank_blockchain_qrcode.png -------------------------------------------------------------------------------- /docs/tutorials/assets/8-for.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/8-for.png -------------------------------------------------------------------------------- /docs/tutorials/assets/10-array.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/10-array.png -------------------------------------------------------------------------------- /docs/tutorials/assets/12-call2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/12-call2.png -------------------------------------------------------------------------------- /docs/tutorials/assets/14-call1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/14-call1.png -------------------------------------------------------------------------------- /docs/tutorials/assets/15-call3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/15-call3.png -------------------------------------------------------------------------------- /docs/tutorials/assets/16-sig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/16-sig.png -------------------------------------------------------------------------------- /docs/tutorials/assets/17-math.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/17-math.png -------------------------------------------------------------------------------- /docs/tutorials/assets/18-call1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/18-call1.png -------------------------------------------------------------------------------- /docs/tutorials/assets/19-call2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/19-call2.png -------------------------------------------------------------------------------- /docs/tutorials/assets/2-remix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/2-remix.png -------------------------------------------------------------------------------- /docs/tutorials/assets/20-proxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/20-proxy.png -------------------------------------------------------------------------------- /docs/tutorials/assets/21-call3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/21-call3.png -------------------------------------------------------------------------------- /docs/tutorials/assets/25-proxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/25-proxy.png -------------------------------------------------------------------------------- /docs/tutorials/assets/26-proxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/26-proxy.png -------------------------------------------------------------------------------- /docs/tutorials/assets/4-solc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/4-solc.png -------------------------------------------------------------------------------- /docs/tutorials/assets/5-run-ev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/5-run-ev.png -------------------------------------------------------------------------------- /docs/tutorials/assets/9-color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/9-color.png -------------------------------------------------------------------------------- /docs/miscs/tutorial/assets/8-for.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/miscs/tutorial/assets/8-for.png -------------------------------------------------------------------------------- /docs/tutorials/assets/1-evm-run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/1-evm-run.png -------------------------------------------------------------------------------- /docs/tutorials/assets/12-account.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/12-account.png -------------------------------------------------------------------------------- /docs/tutorials/assets/22-proxy2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/22-proxy2.png -------------------------------------------------------------------------------- /docs/tutorials/assets/23-proxy3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/23-proxy3.png -------------------------------------------------------------------------------- /docs/tutorials/assets/24-proxy4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/24-proxy4.png -------------------------------------------------------------------------------- /docs/tutorials/assets/6-hello-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/6-hello-1.png -------------------------------------------------------------------------------- /docs/tutorials/assets/6-hello-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/6-hello-2.png -------------------------------------------------------------------------------- /docs/tutorials/assets/6-hello-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/6-hello-3.png -------------------------------------------------------------------------------- /docs/tutorials/assets/6-hello-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/6-hello-4.png -------------------------------------------------------------------------------- /docs/tutorials/assets/6-hello-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/6-hello-5.png -------------------------------------------------------------------------------- /docs/tutorials/assets/6-hello-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/6-hello-6.png -------------------------------------------------------------------------------- /docs/tutorials/assets/6-hello-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/6-hello-7.png -------------------------------------------------------------------------------- /docs/tutorials/assets/6-hello-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/6-hello-8.png -------------------------------------------------------------------------------- /docs/miscs/tutorial/assets/10-array.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/miscs/tutorial/assets/10-array.png -------------------------------------------------------------------------------- /docs/miscs/tutorial/assets/2-remix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/miscs/tutorial/assets/2-remix.png -------------------------------------------------------------------------------- /docs/miscs/tutorial/assets/4-solc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/miscs/tutorial/assets/4-solc.png -------------------------------------------------------------------------------- /docs/miscs/tutorial/assets/5-run-ev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/miscs/tutorial/assets/5-run-ev.png -------------------------------------------------------------------------------- /docs/miscs/tutorial/assets/9-color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/miscs/tutorial/assets/9-color.png -------------------------------------------------------------------------------- /docs/tutorials/assets/11-mapping-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/11-mapping-1.png -------------------------------------------------------------------------------- /docs/tutorials/assets/13-mapping-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/13-mapping-2.png -------------------------------------------------------------------------------- /docs/tutorials/assets/7-msg.sender.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/7-msg.sender.png -------------------------------------------------------------------------------- /docs/miscs/tutorial/assets/1-evm-run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/miscs/tutorial/assets/1-evm-run.png -------------------------------------------------------------------------------- /docs/miscs/tutorial/assets/12-account.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/miscs/tutorial/assets/12-account.png -------------------------------------------------------------------------------- /docs/miscs/tutorial/assets/6-hello-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/miscs/tutorial/assets/6-hello-1.png -------------------------------------------------------------------------------- /docs/miscs/tutorial/assets/6-hello-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/miscs/tutorial/assets/6-hello-2.png -------------------------------------------------------------------------------- /docs/miscs/tutorial/assets/6-hello-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/miscs/tutorial/assets/6-hello-3.png -------------------------------------------------------------------------------- /docs/miscs/tutorial/assets/6-hello-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/miscs/tutorial/assets/6-hello-4.png -------------------------------------------------------------------------------- /docs/miscs/tutorial/assets/6-hello-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/miscs/tutorial/assets/6-hello-5.png -------------------------------------------------------------------------------- /docs/miscs/tutorial/assets/6-hello-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/miscs/tutorial/assets/6-hello-6.png -------------------------------------------------------------------------------- /docs/miscs/tutorial/assets/6-hello-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/miscs/tutorial/assets/6-hello-7.png -------------------------------------------------------------------------------- /docs/miscs/tutorial/assets/6-hello-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/miscs/tutorial/assets/6-hello-8.png -------------------------------------------------------------------------------- /docs/tutorials/assets/3-file-browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/3-file-browser.png -------------------------------------------------------------------------------- /docs/miscs/tutorial/assets/11-mapping-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/miscs/tutorial/assets/11-mapping-1.png -------------------------------------------------------------------------------- /docs/miscs/tutorial/assets/13-mapping-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/miscs/tutorial/assets/13-mapping-2.png -------------------------------------------------------------------------------- /docs/miscs/tutorial/assets/7-msg.sender.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/miscs/tutorial/assets/7-msg.sender.png -------------------------------------------------------------------------------- /docs/tutorials/assets/2-remix-complier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/tutorials/assets/2-remix-complier.png -------------------------------------------------------------------------------- /docs/business_template/CarbonFrugalEvidence.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/business_template/CarbonFrugalEvidence.md -------------------------------------------------------------------------------- /docs/miscs/tutorial/assets/3-file-browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/miscs/tutorial/assets/3-file-browser.png -------------------------------------------------------------------------------- /docs/business_template/medicalCase/assets/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/business_template/medicalCase/assets/1.png -------------------------------------------------------------------------------- /docs/business_template/medicalCase/assets/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/business_template/medicalCase/assets/2.png -------------------------------------------------------------------------------- /docs/business_template/medicalCase/assets/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/business_template/medicalCase/assets/3.png -------------------------------------------------------------------------------- /docs/business_template/medicalCase/assets/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/business_template/medicalCase/assets/4.png -------------------------------------------------------------------------------- /docs/business_template/medicalCase/assets/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/business_template/medicalCase/assets/5.png -------------------------------------------------------------------------------- /docs/business_template/medicalCase/assets/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/business_template/medicalCase/assets/6.png -------------------------------------------------------------------------------- /docs/business_template/medicalCase/assets/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/business_template/medicalCase/assets/7.png -------------------------------------------------------------------------------- /docs/business_template/medicalCase/assets/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/business_template/medicalCase/assets/8.png -------------------------------------------------------------------------------- /docs/business_template/medicalCase/assets/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/business_template/medicalCase/assets/9.png -------------------------------------------------------------------------------- /docs/miscs/tutorial/assets/2-remix-complier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/SmartDev-Contract/HEAD/docs/miscs/tutorial/assets/2-remix-complier.png -------------------------------------------------------------------------------- /contracts/default/proxy/ISing.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | /** 4 | * @author SomeJoker 5 | * @title 接口 6 | */ 7 | interface ISing{ 8 | function singing(address singer) external; 9 | } -------------------------------------------------------------------------------- /docs/business_template/evidence_plus.md: -------------------------------------------------------------------------------- 1 | # 存证合约 Plus 版本 2 | 3 | **业务需求:** 4 | 5 | 在部分场景中,需对合约 Key 进行指定。 6 | 7 | 因此,对原有 Evidence 存证合约进行了增强。 8 | 9 | **新功能点描述:** 10 | 11 | 增强功能点包括: 12 | 13 | - 增加 newEvidenceEventWithKey 事件 14 | - 增加 newEvidenceByKey 方法 15 | - 增加 getEvidenceByKey 方法 16 | -------------------------------------------------------------------------------- /contracts/default/proxy/Sing.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | import "./ISing.sol"; 4 | /** 5 | * @author SomeJoker 6 | * @title 实现 7 | */ 8 | contract Sing is ISing{ 9 | 10 | event SingLog(address singer,uint256 time); 11 | 12 | function singing(address _singer) public { 13 | emit SingLog(_singer, now); 14 | } 15 | } -------------------------------------------------------------------------------- /docs/common_tools/counter.sol.md: -------------------------------------------------------------------------------- 1 | # counter.sol 2 | counter合约提供计数器的创建、加、减以及归零操作 3 | 4 | # 函数说明 5 | counterAdd 6 | 调用时,传入要使用的计数器id,即可对该计数器进行加操作,若操作时未发现该计数器,则创建。同时过程中记录日志 7 | 8 | counterSub 9 | 调用时,传入要使用的计数器id,即可对该计数器进行减操作,若操作时未发现该计数器,则创建,且计数器结果为0。同时过程中记录日志 10 | 11 | counterClear 12 | 调用时,传入要使用的计数器id,即可对该计数器进行归零操作,同时过程中记录日志 13 | 14 | getCounter 15 | 调用时传入计数器id,返回该计数器当前的计数值 -------------------------------------------------------------------------------- /contracts/default/HelloWorld.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | contract HelloWorld { 4 | string name; 5 | 6 | constructor() public { 7 | name = "Hello, World!"; 8 | } 9 | 10 | function get() public view returns (string memory) { 11 | return name; 12 | } 13 | 14 | function set(string memory n) public { 15 | name = n; 16 | } 17 | } -------------------------------------------------------------------------------- /contracts/common_tools/privacy_computation/Fiat-Shamir-ZK/contract_step2.py: -------------------------------------------------------------------------------- 1 | import libnum 2 | import hashlib 3 | import random 4 | n=8269 5 | g=11 6 | 7 | v = random.randint(1,n) 8 | 9 | print('\n======Phase 2: Peggy wants to login , She send t to Victor==================') 10 | v = random.randint(1,n) 11 | t = pow(g,v,n) 12 | print('v=',v,'\t(Peggy\'s random value)') 13 | print('t=g**v % n =\t\t',t) -------------------------------------------------------------------------------- /docs/business_template/SimplePoint.md: -------------------------------------------------------------------------------- 1 | ## 功能说明 2 | 本合约为积分合约demo,获取积分和转账积分功能。 3 | 4 | ## 接口 5 | 提供了PointDemo合约,主要是获取积分和转账积分功能 6 | - mint(address receiver,uint amount):获取积分 7 | - send(address receiver,uint amount): 转账积分 8 | 9 | 10 | ## 使用示例 11 | 积分合约获取积分和转账积分,整个过程如下: 12 | 13 | 合约初始化: 14 | 15 | - 部署PointDemo合约 16 | 17 | 合约调用: 18 | 19 | - 调用PointDemo.mint 获取积分 20 | - 调用PointDemo.send 转账积分 21 | -------------------------------------------------------------------------------- /contracts/business_template/Medicine/mocks/BasicTokenMock.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.21; 2 | 3 | import "../BasicToken.sol"; 4 | 5 | // mock class using BasicToken 6 | contract BasicTokenMock is BasicToken { 7 | 8 | constructor(address initialAccount, uint256 initialBalance) public { 9 | balances[initialAccount] = initialBalance; 10 | totalSupply_ = initialBalance; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /contracts/business_template/Medicine/mocks/StandardTokenMock.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.21; 2 | 3 | import "../StandardToken.sol"; 4 | 5 | // mock class using StandardToken 6 | contract StandardTokenMock is StandardToken { 7 | 8 | constructor(address initialAccount, uint256 initialBalance) public { 9 | balances[initialAccount] = initialBalance; 10 | totalSupply_ = initialBalance; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /contracts/business_template/carbon_frugal_evidence/Address.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | library Address { 4 | 5 | function isContract(address addr) internal view returns(bool) { 6 | uint256 size; 7 | assembly { size := extcodesize(addr) } 8 | return size > 0; 9 | } 10 | 11 | function isEmptyAddress(address addr) internal pure returns(bool){ 12 | return addr == address(0); 13 | } 14 | } -------------------------------------------------------------------------------- /contracts/default/crypto/Crypto.sol: -------------------------------------------------------------------------------- 1 | contract Crypto 2 | { 3 | function sm3(bytes memory data) public view returns(bytes32){} 4 | function keccak256Hash(bytes memory data) public view returns(bytes32){} 5 | function sm2Verify(bytes32 message, bytes memory publicKey, bytes32 r, bytes32 s) public view returns(bool, address){} 6 | function curve25519VRFVerify(string memory input, string memory vrfPublicKey, string memory vrfProof) public view returns(bool,uint256){} 7 | } -------------------------------------------------------------------------------- /contracts/common_tools/privacy_computation/Fiat-Shamir-ZK/contract_step45.py: -------------------------------------------------------------------------------- 1 | import libnum 2 | import hashlib 3 | import random 4 | n=8269 5 | g=11 6 | 7 | password = "Hello" 8 | x = int(hashlib.sha256(password.encode()).hexdigest()[:8], 16) % n 9 | 10 | 11 | print('\n======Phase 4: Peggy recieves c and calculate r=v-cx, sends r to Victor==================') 12 | c = input("c= ") 13 | v = input("v= ") 14 | r = (int(v) - int(c) * x) % (n-1) 15 | 16 | print('r=v-cx =\t\t',r) -------------------------------------------------------------------------------- /contracts/common_tools/privacy_computation/Fiat-Shamir-ZK/contract_step1.py: -------------------------------------------------------------------------------- 1 | import libnum 2 | import hashlib 3 | n=8269 4 | g=11 5 | 6 | password = "Hello" 7 | 8 | print("Password:\t\t",password) 9 | x = int(hashlib.sha256(password.encode()).hexdigest()[:8], 16) % n 10 | print("Password hash(x):\t",x,"\t (last 8 bits)") 11 | 12 | print('\n======Phase 1: Peggy sends y to Victor,Victor store y as Peggy\' token==================') 13 | y= pow(g,x,n) 14 | print('y= g^x mod P=\t\t',y) -------------------------------------------------------------------------------- /contracts/common_tools/base64/LibBase64Test.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | import "./LibBase64.sol"; 3 | 4 | contract LibBase64 { 5 | function test_encode() public pure returns (string memory) { 6 | string memory _str = "hello world"; 7 | return LibBase64.encode(_str); 8 | } 9 | 10 | function test_decode() public pure returns (string memory) { 11 | string memory _str = "aGVsbG8gd29ybGQ="; 12 | return LibBase64.decode(_str); 13 | } 14 | } -------------------------------------------------------------------------------- /docs/common_tools/FuncCallContract.md: -------------------------------------------------------------------------------- 1 | ## function 2 | - 继承该合约后能够使用其`LogFuncCall`修饰器以触发想要监听的函数调用,事件中内容包括`msg.sender, tx.origin, func, args` 3 | 4 | ## usage 5 | - 继承该合约,然后在想要监听的函数上使用`LogFuncCall`修饰器即可,如: 6 | ```solidity 7 | contract Test is FuncCallContract { 8 | function test(uint256 x) 9 | external 10 | LogFuncCall("test(uint256)") 11 | returns (uint256) 12 | { 13 | return x + 233; 14 | } 15 | } 16 | ``` 17 | 18 | ## for DApps 19 | - 该功能可以帮助DApp的开发,如果DApp需要监听某个函数调用,可通过继承该合约实现想要的功能 -------------------------------------------------------------------------------- /contracts/business_template/Medicine/ERC20Basic.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.21; 2 | 3 | /** 4 | * @title ERC20Basic 5 | * @dev Simpler version of ERC20 interface 6 | * @dev see https://github.com/ethereum/EIPs/issues/179 7 | */ 8 | contract ERC20Basic { 9 | function totalSupply() public view returns (uint256); 10 | function balanceOf(address who) public view returns (uint256); 11 | function transfer(address to, uint256 value) public returns (bool); 12 | event Transfer(address indexed from, address indexed to, uint256 value); 13 | } 14 | -------------------------------------------------------------------------------- /contracts/business_template/divergence/IDivergence.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity^0.6.10; 3 | 4 | // 定义接口 5 | interface IDivergence { 6 | // 注册 7 | function register(string memory _name) external; 8 | // 出手 9 | function punch(bytes32 _hash) external; 10 | // 证明 11 | function proofing(string memory _salt, uint8 _opt) external; 12 | // 查看获胜 13 | // 返回值: 1. 昵称 2. 玩家1出手 3. 玩家2出手 4. 轮次 14 | function winner() external view returns (string memory, string memory, string memory, uint256); 15 | } 16 | -------------------------------------------------------------------------------- /contracts/default/proxy/SingProxy.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | import "./ISing.sol"; 4 | 5 | /** 6 | * @author SomeJoker 7 | * @title 代理 8 | */ 9 | contract SingProxy{ 10 | 11 | event ProxyLog(address singer,string context); 12 | 13 | ISing iSing; 14 | constructor(address _sing) public{ 15 | iSing = ISing(_sing); 16 | } 17 | 18 | function proxySing() public { 19 | emit ProxyLog(msg.sender,"before proxy do someting"); 20 | iSing.singing(msg.sender); 21 | emit ProxyLog(msg.sender,"after proxy do someting"); 22 | } 23 | } -------------------------------------------------------------------------------- /contracts/business_template/Medicine/ERC20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.21; 2 | 3 | import "./ERC20Basic.sol"; 4 | 5 | /** 6 | * @title ERC20 interface 7 | * @dev see https://github.com/ethereum/EIPs/issues/20 8 | */ 9 | contract ERC20 is ERC20Basic { 10 | function allowance(address owner, address spender) public view returns (uint256); 11 | function transferFrom(address from, address to, uint256 value) public returns (bool); 12 | function approve(address spender, uint256 value) public returns (bool); 13 | event Approval(address indexed owner, address indexed spender, uint256 value); 14 | } 15 | -------------------------------------------------------------------------------- /contracts/business_template/divergence/LibGameCompare.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | 3 | // 定义library 计算获胜方 4 | library LibGameCompare { 5 | // 玩家1 & 玩家2 6 | // 返回值: 0 - 相等 ; 1 - 大于 ; 2 - 小于 7 | function max(uint8 a, uint8 b) internal pure returns (uint8) { 8 | require(a <= 2); 9 | require(b <= 2); 10 | if(a == b) { 11 | return 0; 12 | } else if(a > b) { 13 | // 1 ,0 ; 2,1; 2, 0 14 | return a - b; 15 | 16 | } else { 17 | if(b - a == 2) return 1; 18 | if(b - a == 1) return 2; 19 | } 20 | 21 | return 0; 22 | } 23 | } -------------------------------------------------------------------------------- /contracts/business_template/Medicine/mocks/SafeMathMock.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.21; 2 | 3 | import "../SafeMath.sol"; 4 | 5 | contract SafeMathMock { 6 | 7 | function mul(uint256 a, uint256 b) public pure returns (uint256) { 8 | return SafeMath.mul(a, b); 9 | } 10 | 11 | function div(uint256 a, uint256 b) public pure returns (uint256) { 12 | return SafeMath.div(a, b); 13 | } 14 | 15 | function sub(uint256 a, uint256 b) public pure returns (uint256) { 16 | return SafeMath.sub(a, b); 17 | } 18 | 19 | function add(uint256 a, uint256 b) public pure returns (uint256) { 20 | return SafeMath.add(a, b); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /contracts/business_template/Medicine/Migrations.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.21; 2 | 3 | contract Migrations { 4 | address public owner; 5 | uint public last_completed_migration; 6 | 7 | modifier restricted() { 8 | if (msg.sender == owner) _; 9 | } 10 | 11 | constructor() public { 12 | owner = msg.sender; 13 | } 14 | 15 | function setCompleted(uint completed) public restricted { 16 | last_completed_migration = completed; 17 | } 18 | 19 | function upgrade(address new_address) public restricted { 20 | Migrations upgraded = Migrations(new_address); 21 | upgraded.setCompleted(last_completed_migration); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /docs/base_type/Counters.md: -------------------------------------------------------------------------------- 1 | # 计数器 2 | 提供只能递增或递减1的计数器。这可以用于例如 跟踪铸造的ERC721的id或计数请求id。 3 | 4 | ## API列表 5 | 6 | 编号 | API | API描述 7 | ---|---|--- 8 | 1 | *current(Counter storage counter) internal view returns (uint256)* | 获取计数器当前值 9 | 2 | *increment(Counter storage counter) internal* | 计数器递增1 10 | 3 | *decrement(Counter storage counter) internal* | 计数器递减1 11 | 12 | 13 | ## API 详情 14 | 15 | ### ***1. current 函数*** 16 | 获取计数器当前值 17 | #### 参数 18 | - Counter: 计数器本身 19 | #### 返回值 20 | - Counter的当前值 21 | 22 | ### ***2. increment 函数*** 23 | 计数器递增1 24 | #### 参数 25 | - Counter: 计数器本身 26 | #### 返回值 27 | - 无 28 | 29 | ### ***3. decrement 函数*** 30 | 计数器递减1 31 | #### 参数 32 | - Counter: 计数器本身 33 | #### 返回值 34 | - 无 -------------------------------------------------------------------------------- /contracts/default/crypto/ShaTest.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | pragma experimental ABIEncoderV2; 4 | 5 | import "./Crypto.sol"; 6 | 7 | contract ShaTest{ 8 | bytes _data = "Hello, ShaTest"; 9 | Crypto crypto; 10 | 11 | constructor() public { 12 | crypto = Crypto(0x5006); 13 | } 14 | 15 | function getSha256(bytes memory _memory) public returns(bytes32 result) 16 | { 17 | return sha256(_memory); 18 | } 19 | 20 | function getKeccak256(bytes memory _memory) public returns(bytes32 result) 21 | { 22 | return keccak256(_memory); 23 | } 24 | 25 | function getData() public view returns(bytes memory) 26 | { 27 | return _data; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /contracts/business_template/CharityFund/Roles.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | library Roles { 4 | struct Role { 5 | mapping (address => bool) bearer; 6 | } 7 | 8 | function add(Role storage role, address account) internal { 9 | require(!has(role, account), "当前角色还没有权限"); 10 | role.bearer[account] = true; 11 | } 12 | 13 | function remove(Role storage role, address account) internal { 14 | require(has(role, account), "当前角色还没有权限"); 15 | role.bearer[account] = false; 16 | } 17 | 18 | function has(Role storage role, address account) internal view returns (bool) { 19 | require(account != address(0), "当前地址为空"); 20 | return role.bearer[account]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /contracts/base_type/string/StringDemo.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | import "./LibString.sol"; 3 | 4 | contract StringDemo { 5 | 6 | function demo1() public{ 7 | string memory str = "你好"; 8 | uint256 lenOfChars = LibString.lenOfChars(str); 9 | uint256 lenOfBytes = LibString.lenOfBytes(str); 10 | require(lenOfChars == 2); 11 | require(lenOfBytes == 6); 12 | } 13 | 14 | function demo2() public view returns(string memory) { 15 | string memory c = LibString.toUppercase("abcd");// Expected to be ABCD 16 | return c; 17 | } 18 | 19 | function demo3() public view { 20 | bool r = LibString.equal("abcd","abcd");//Expected to be true 21 | require(r); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /contracts/common_tools/batch_execution_contract/BatchExecutionTest.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.6.10; 3 | 4 | contract BatchExecutionTest{ 5 | struct User{ 6 | string name; 7 | uint256 age; 8 | } 9 | 10 | mapping(uint256 => User) userMap; 11 | 12 | //存储数据,方便查看测试结果 13 | User[] userList; 14 | 15 | function setUser(uint256 id,string memory name,uint256 age) public { 16 | User memory user = User(name,age); 17 | userMap[id] = user; 18 | userList.push(user); 19 | } 20 | 21 | function getUser(uint256 id) public view returns(string memory,uint256){ 22 | User memory user = userMap[id]; 23 | return (user.name,user.age); 24 | } 25 | } -------------------------------------------------------------------------------- /contracts/common_tools/role/RBAC/Roles.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.6.10; 2 | /** 3 | * @author SomeJoker 4 | * @title 角色 5 | */ 6 | library Roles{ 7 | 8 | struct Role{ 9 | mapping(address => bool) bearer; 10 | } 11 | 12 | function addRole(Role storage role ,address addr) internal{ 13 | role.bearer[addr] = true; 14 | } 15 | 16 | function removeRole(Role storage role,address addr) internal{ 17 | role.bearer[addr] = false; 18 | } 19 | 20 | function hasRole(Role storage role,address addr) internal view returns(bool){ 21 | return role.bearer[addr]; 22 | } 23 | 24 | function checkRole(Role storage role,address addr) public view{ 25 | require(hasRole(role, addr)); 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /contracts/common_tools/multi_call/MultiCall.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | /// @author tianlan 3 | 4 | pragma solidity >=0.8.0; 5 | 6 | contract MultiCall { 7 | function call( 8 | address[] calldata addrs, 9 | bytes[] calldata data 10 | ) external view returns (bytes[] memory) { 11 | require(addrs.length == data.length, "target length != data length"); 12 | 13 | bytes[] memory results = new bytes[](data.length); 14 | 15 | for (uint i; i < addrs.length; i++) { 16 | (bool success, bytes memory result) = addrs[i].staticcall(data[i]); 17 | require(success, "call failed"); 18 | results[i] = result; 19 | } 20 | 21 | return results; 22 | } 23 | } 24 | 25 | 26 | -------------------------------------------------------------------------------- /contracts/business_template/simple_point/SimplePointDemo.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | contract PointDemo{ 4 | 5 | address public minter; 6 | 7 | mapping(address => uint) public balances; 8 | 9 | event Sent(address from,address to,uint amount); 10 | constructor() public{ 11 | minter = msg.sender; 12 | } 13 | function mint(address receiver,uint amount) public{ 14 | require(msg.sender == minter); 15 | balances[receiver] += amount; 16 | } 17 | 18 | function send(address receiver,uint amount) public{ 19 | require(amount <= balances[msg.sender]); 20 | balances[msg.sender] -= amount; 21 | balances[receiver] += amount; 22 | emit Sent(msg.sender,receiver,amount); 23 | } 24 | } -------------------------------------------------------------------------------- /docs/common_tools/LibBase64.md: -------------------------------------------------------------------------------- 1 | # LibBase64.sol 2 | 3 | LibBase64 提供Base64编解码 4 | 5 | 6 | ## 接口说明 7 | 1. function encode(string memory data) returns(string memory):Base64编码 8 | - data:要编码的数据 9 | 10 | 2. function decode(string memory data) returns(string memory):Base64解码 11 | - data:要解码的数据 12 | 13 | ## 使用方法 14 | 15 | ``` 16 | pragma solidity ^0.4.25; 17 | import "./LibBase64.sol"; 18 | 19 | contract LibBase64 { 20 | function test_encode() public pure returns (string memory) { 21 | string memory _str = "hello world"; 22 | return LibBase64.encode(_str); 23 | } 24 | 25 | function test_decode() public pure returns (string memory) { 26 | string memory _str = "aGVsbG8gd29ybGQ="; 27 | return LibBase64.decode(_str); 28 | } 29 | } 30 | 31 | ``` -------------------------------------------------------------------------------- /contracts/default/crypto/gm/ICrypto.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.0; 2 | 3 | // 预编译合约接口定义 4 | interface ICrypto{ 5 | //使用国密sm3算法计算指定数据的哈希; 6 | function sm3(bytes calldata data) external pure returns(bytes32); 7 | //使用keccak256算法计算指定数据的哈希; 8 | function keccak256Hash(bytes calldata data) external pure returns(bytes32); 9 | //使用sm2算法验证签名(publicKey, r, s)是否有效,验证通过返回true以及通过公钥推导出的国密账户,验证失败返回false和地址全0的账户; 10 | function sm2Verify(bytes32 message, bytes calldata publicKey, bytes32 r, bytes32 s) external pure returns(bool, address); 11 | //给定VRF输入和VRF公钥,使用基于ed25519曲线的VRF算法验证VRF证明是否有效,若VRF证明验证成功,返回true以及根据证明推导出来的VRF随机数;若VRF证明验证失败,则返回(false, 0) 12 | function curve25519VRFVerify(string calldata input, string calldata vrfPublicKey, string calldata vrfProof) external pure returns(bool,uint256); 13 | } -------------------------------------------------------------------------------- /docs/default/crypto/Crypto.md: -------------------------------------------------------------------------------- 1 | # Crypto.sol 2 | 3 | Crypto提供了密码学操作 4 | 5 | ## 使用方法 6 | 7 | ``` 8 | pragma solidity >=0.4.24 <0.6.11; 9 | 10 | pragma experimental ABIEncoderV2; 11 | 12 | import "./Crypto.sol"; 13 | 14 | contract ShaTest{ 15 | bytes _data = "Hello, ShaTest"; 16 | Crypto crypto; 17 | 18 | constructor() public { 19 | crypto = Crypto(0x5006); 20 | } 21 | 22 | function getSha256(bytes memory _memory) public returns(bytes32 result) 23 | { 24 | return sha256(_memory); 25 | } 26 | 27 | function getKeccak256(bytes memory _memory) public returns(bytes32 result) 28 | { 29 | return keccak256(_memory); 30 | } 31 | 32 | function getData() public view returns(bytes memory) 33 | { 34 | return _data; 35 | } 36 | } 37 | 38 | ``` -------------------------------------------------------------------------------- /contracts/common_tools/math/MathAdvanceTest.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | import "./MathAdvance.sol"; 4 | 5 | contract MathAdvanceTest{ 6 | 7 | function sqrt(uint x) public view returns (uint){ 8 | return MathAdvance.sqrt(x); // x = 4 ,return 2 9 | } 10 | 11 | function log2(uint x) public view returns(uint) { 12 | return MathAdvance.log2(x); //x = 2, return 1 13 | } 14 | 15 | function log(uint m, uint n) public view returns(uint) { 16 | return MathAdvance.log(m, n); //m = 10, n = 100, return 2 17 | } 18 | 19 | function exp2(int n) public view returns(uint) { 20 | return MathAdvance.exp2(n); //n = 2, return 4 21 | } 22 | 23 | function exp(int m, int n) public view returns(int) { 24 | return MathAdvance.exp(m, n); //m = +-2, n =2, return 4; m=-2, n=1, return -2 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /contracts/base_type/array/ArrayDemo.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | import "./LibArrayForUint256Utils.sol"; 3 | contract ArrayDemo { 4 | 5 | uint[] private array; 6 | uint[] private array1; 7 | uint[] private array2; 8 | 9 | function f1() public view { 10 | array=new uint[](0); 11 | // array add element 2 12 | LibArrayForUint256Utils.addValue(array,2); 13 | // array: {2} 14 | } 15 | 16 | 17 | function f2() public view { 18 | array1=new uint[](2); 19 | array2=new uint[](2); 20 | LibArrayForUint256Utils.extend(array1,array2); 21 | // array1 length 4 22 | } 23 | 24 | function f3() public view { 25 | array=new uint[](2); 26 | array[0]=2; 27 | array[1]=2; 28 | LibArrayForUint256Utils.distinct(array); 29 | // array: {2} 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /contracts/base_type/Counters.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | /** 4 | * @title Counters 5 | * @author SomeJoker 6 | * @dev 提供只能递增或递减1的计数器。这可以用于例如 跟踪铸造的ERC721的id或计数请求id。 7 | * 8 | * 用法: `using Counters for Counters.Counter;` 9 | */ 10 | library Counters { 11 | struct Counter { 12 | uint256 _value; // default: 0 13 | } 14 | 15 | function current(Counter storage counter) internal view returns (uint256) { 16 | return counter._value; 17 | } 18 | 19 | function increment(Counter storage counter) internal { 20 | // 以1为增量,要达到2^256=1.1579209e+77,几乎不存在这样的场景,所以跳过了加法的安全检查,以节省gas 21 | counter._value += 1; 22 | } 23 | 24 | function decrement(Counter storage counter) internal { 25 | require(counter._value >= 1, "Counters decrement: subtraction overflow"); 26 | counter._value = counter._value - 1; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /contracts/data_structure/map/LibBytesMapDemo.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | import "./LibBytesMap.sol"; 3 | 4 | contract LibBytesMapDemo { 5 | using LibBytesMap for LibBytesMap.Map; 6 | 7 | LibBytesMap.Map private map; 8 | 9 | event Log(bytes key, uint256 index); 10 | 11 | function f() public { 12 | string memory k1 = "k1"; 13 | string memory k2 = "k2"; 14 | string memory k3 = "k3"; 15 | string memory v1 = "v1"; 16 | string memory v2 = "v2"; 17 | string memory v3 = "v3"; 18 | map.put(bytes(k1), bytes(v1)); 19 | map.put(bytes(k2), bytes(v2)); 20 | map.put(bytes(k3), bytes(v3)); 21 | 22 | uint256 i = map.iterate_start(); 23 | 24 | while (map.can_iterate(i)) { 25 | emit Log(map.getKeyByIndex(i), i); 26 | i = map.iterate_next(i); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /contracts/base_type/LibAsciiDemo.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | import "./LibAscii.sol"; 4 | 5 | contract LibAsciiDemo{ 6 | 7 | function ascii2str() public pure returns(string,string,string,string){ 8 | //10进制ascii转字符串 9 | string memory result= LibAscii.decAscii2str("55"); 10 | //result:"7" 11 | string memory result1= LibAscii.decAscii2str("109"); 12 | //result:"m" 13 | 14 | //16进制ascii转字符串 15 | string memory result2= LibAscii.hexAscii2str("37"); 16 | //result1:"7" 17 | string memory result3= LibAscii.hexAscii2str("6D"); 18 | //result1:"m" 19 | 20 | return (result,result1,result2,result3); 21 | } 22 | 23 | function str2ascii() public pure returns(string){ 24 | string memory result=LibAscii.str2ascii("Zz"); 25 | //result:"90122" 26 | return result; 27 | } 28 | } -------------------------------------------------------------------------------- /contracts/common_tools/MultiSign/MultiSignDemo.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | /// @author Steve Jin 3 | 4 | pragma solidity >=0.8.0; 5 | 6 | import {MultiSign} from "./MultiSign.sol"; 7 | 8 | contract MultiSignDemo is MultiSign { 9 | 10 | event MultiSignLog(address from, address to, bytes data, address[] signers, uint signCount); 11 | 12 | address public owner; 13 | 14 | uint public signFinishedCallBackCount = 0; 15 | 16 | constructor(address[] memory addressParams, uint minSignaturesParam) MultiSign(addressParams, minSignaturesParam) { 17 | owner = msg.sender; 18 | } 19 | 20 | function signFinishedCallBack(Transaction storage transaction) override internal { 21 | emit MultiSignLog(transaction.from, transaction.to, transaction.data, transaction.signers, transaction.signCount); 22 | signFinishedCallBackCount++; 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /contracts/common_tools/func_call_contract/FuncCallContract.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | contract FuncCallContract { 4 | event FuncCall( 5 | address indexed _from, 6 | address indexed _origin, 7 | string _func, 8 | bytes _args 9 | ); 10 | 11 | modifier LogFuncCall(string memory func) { 12 | uint256 len = 0; 13 | assembly { 14 | len := calldatasize() // 36 15 | } 16 | bytes memory args = new bytes(len); 17 | assembly { 18 | calldatacopy(add(args, 0x20), 0, len) 19 | } 20 | emit FuncCall(msg.sender, tx.origin, func, args); 21 | _; 22 | } 23 | } 24 | 25 | contract Test is FuncCallContract { 26 | function test(uint256 x) 27 | external 28 | LogFuncCall("test(uint256)") 29 | returns (uint256) 30 | { 31 | return x + 233; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /contracts/common_tools/timelock/TimelockTest.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.6.10; 2 | 3 | /* 4 | * @dev 时间锁测试合约测试 5 | */ 6 | contract TimelockTest{ 7 | address private timelock; 8 | 9 | struct User{ 10 | string name; 11 | uint256 age; 12 | } 13 | 14 | mapping(uint256 => User) userMap; 15 | 16 | constructor(address _timelockAddress) public { 17 | timelock = _timelockAddress; 18 | } 19 | 20 | modifier onlyTimelock(){ 21 | require(msg.sender == timelock,"Call must come from Timelock"); 22 | _; 23 | } 24 | 25 | function addUser(uint256 id,string memory name,uint256 age) public onlyTimelock{ 26 | User memory user = User(name,age); 27 | userMap[id] = user; 28 | } 29 | 30 | function getUser(uint256 id) public view returns(string memory,uint256){ 31 | User memory user = userMap[id]; 32 | return (user.name,user.age); 33 | } 34 | } -------------------------------------------------------------------------------- /contracts/data_structure/set/AddressSetDemo.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | import "./LibAddressSet.sol"; 4 | 5 | contract AddressSetDemo { 6 | using LibAddressSet for LibAddressSet.AddressSet; 7 | LibAddressSet.AddressSet private addressSet; 8 | 9 | event Log(uint256 size); 10 | 11 | function testAddress() public { 12 | //添加元素; 13 | addressSet.add(address(1)); 14 | // {1} 15 | // 查询set容器数量 16 | uint256 size = addressSet.getSize(); 17 | require(size == 1); 18 | // 获取指定index的元素 19 | address addr = addressSet.get(0); 20 | require(addr == (address(1))); 21 | // 返回set中所有的元素 22 | addressSet.getAll(); 23 | // {0x1} 24 | // 判断元素是否存在 25 | bool contains = addressSet.contains(address(1)); 26 | require(contains== true); 27 | // 删除元素 28 | addressSet.remove(address(1)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /contracts/default/crypto/LibCryptoHash.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | library LibCryptoHash { 4 | event TestLog(bytes32 value); 5 | 6 | function getKeccak256(string memory s1) internal returns(bytes32 result){ 7 | bytes32 a = keccak256(abi.encodePacked(s1)); 8 | emit TestLog(a); 9 | 10 | return a; 11 | } 12 | 13 | function getSha3(string memory s1) internal returns(bytes32 result){ 14 | bytes32 a = sha3(bytes(s1)); 15 | emit TestLog(a); 16 | return a; 17 | 18 | } 19 | 20 | function getSha256(string memory s1) internal returns(bytes32 result){ 21 | bytes32 a = sha256(bytes(s1)); 22 | emit TestLog(a); 23 | return a; 24 | 25 | } 26 | 27 | function getRipemd160(string memory s1) internal returns(bytes20 result){ 28 | bytes20 a = ripemd160(bytes(s1)); 29 | emit TestLog(a); 30 | return a; 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /contracts/common_tools/role/white_list/SafeRole.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | 4 | library SafeRole { 5 | struct Role { 6 | mapping (address => bool) bearer; 7 | } 8 | 9 | /** 10 | * 给账户赋予角色. 11 | */ 12 | function add(Role storage role, address account) internal { 13 | require(!has(role, account), "Roles: account already has role"); 14 | role.bearer[account] = true; 15 | } 16 | 17 | /** 18 | * 账户移除角色 19 | */ 20 | function remove(Role storage role, address account) internal { 21 | require(has(role, account), "Roles: account does not have role"); 22 | role.bearer[account] = false; 23 | } 24 | 25 | /** 26 | * 判断账户是否有此角色 27 | */ 28 | function has(Role storage role, address account) internal view returns (bool) { 29 | require(account != address(0), "Roles: account is the zero address"); 30 | return role.bearer[account]; 31 | } 32 | } -------------------------------------------------------------------------------- /contracts/business_template/chattel/role/Role.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | import "./RoleStorage.sol"; 4 | 5 | contract Role { 6 | 7 | string constant private DK_Role = "DK"; // 货款方 8 | string constant private ZJ_Role = "ZJ"; // 资金方 9 | string constant private JG_Role = "JG"; // 监管方 10 | 11 | RoleStorage private roleStorage; 12 | 13 | constructor() public { 14 | roleStorage = new RoleStorage(); 15 | } 16 | 17 | function onlyDKRole(string memory _user_id) public view{ 18 | require(roleStorage.hasRole(DK_Role, _user_id), "not has dk permission"); 19 | } 20 | 21 | function onlyZJRole(string memory _user_id) public view{ 22 | require(roleStorage.hasRole(ZJ_Role, _user_id), "not has zj permission"); 23 | } 24 | 25 | function onlyJGRole(string memory _user_id) public view{ 26 | require(roleStorage.hasRole(JG_Role, _user_id), "not has jg permission"); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /contracts/business_template/red_packet/IERC20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity^0.6.10; 2 | 3 | //定义接口 4 | interface IERC20 { 5 | 6 | function name() external view returns (string memory); 7 | function symbol() external view returns (string memory); 8 | function totalSupply() external view returns (uint256); 9 | function balanceOf(address _owner) external view returns (uint256 balance); 10 | function transfer(address _to, uint256 _value) external returns (bool success); 11 | function approve(address _spender, uint256 _value) external returns (bool success); 12 | function transferFrom(address _from, address _to, uint256 _value) external returns (bool success); 13 | function allowance(address _owner, address _spender) external view returns (uint256 remaining); 14 | 15 | 16 | 17 | event Transfer(address indexed _from, address indexed _to, uint256 _value); 18 | event Approval(address indexed _owner, address indexed _spender, uint256 _value); 19 | 20 | } -------------------------------------------------------------------------------- /contracts/common_tools/role/RBAC/Ownable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.6.10; 2 | 3 | 4 | /** 5 | * @author SomeJoker 6 | * @title Ownable 7 | */ 8 | contract Ownable{ 9 | address public owner; 10 | 11 | event OwnershipRenounced(address indexed lastOwner); 12 | event OwnershipTransfer(address indexed lastOwner,address indexed currentOwner); 13 | 14 | constructor() public{ 15 | owner = msg.sender; 16 | } 17 | 18 | modifier onlyOwner{ 19 | require(msg.sender == owner, "msg.sender is not owner"); 20 | _; 21 | } 22 | 23 | function renounceOwnership() public onlyOwner{ 24 | emit OwnershipRenounced(owner); 25 | owner = address(0); 26 | } 27 | 28 | function transferOwnership(address _newOwner) public onlyOwner { 29 | require(_newOwner != address(0),"_newOwner Can't be Zero address"); 30 | emit OwnershipTransfer(owner,_newOwner); 31 | owner = _newOwner; 32 | } 33 | } -------------------------------------------------------------------------------- /docs/common_tools/MultiSign.md: -------------------------------------------------------------------------------- 1 | ## 说明 2 | 发起一个事务后,需多方签名后才能执行该事务。 3 | 4 | ## 使用 5 | > 参考 MultiSignDemo.sol 6 | - 继承该合约 `MultiSign.sol` 7 | - `constructor` 传入 `address[]`, `uint` 8 | - address[]: 可以签名的地址集合。 9 | - uint: 最小签名个数,满足这个数量时此事务完成多签。 10 | - 重写 `signFinishedCallBack` 方法 11 | - 多签完成后,会回调执行此方法。 12 | 13 | ## 接口 14 | - showSigner(): 列出所有可以签名的地址 15 | - showNextTransactionIdx(): 列出下一个事务ID 16 | - showPendingTransactions(): 列出所有待签名的事务ID 17 | - transfer(address to, bytes memory data): 添加新事务,返回事务ID 18 | - signTransaction(uint transactionId): 给事务签名,transactionId是事务ID,返回是否完成签名 19 | - signFinished(uint transactionId): 获取事务多签完成情况,transactionId是事务ID,返回是否完成签名 20 | - signFinishedCallBack(Transaction storage transaction): 重写此方法,完成多签后,会回调此方法 21 | 22 | ## 示例 23 | > 参考 MultiSignDemo.sol 24 | 25 | 1. 部署 `MultiSignDemo.sol` 传入 `可以签名的地址集合`, `最小签名个数` 26 | 27 | 2. 调用 `transfer` 添加新事务 28 | 29 | 3. 其他可以签名的地址调用 `signTransaction` 给指定事务签名 30 | 31 | 4. 多签完成回调 `signFinishedCallBack` 方法 32 | -------------------------------------------------------------------------------- /contracts/common_tools/multi_call/MultiCallTest.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | /// @author tianlan 3 | 4 | pragma solidity >=0.8.0; 5 | 6 | import "./MultiCall.sol"; 7 | 8 | contract MultiCallTest { 9 | MultiCall public _multi; 10 | 11 | constructor(MultiCall multi) { 12 | _multi = multi; 13 | } 14 | 15 | function show(uint value) external pure returns (uint) { 16 | return value; 17 | } 18 | 19 | function getData(uint value) internal pure returns (bytes memory) { 20 | return abi.encodeWithSelector(this.show.selector, value); 21 | } 22 | 23 | function testMultiCall() external view returns (bytes[] memory) { 24 | address[] memory addr = new address[](2); 25 | addr[0] = address(this); 26 | addr[1] = address(this); 27 | 28 | bytes[] memory data = new bytes[](2); 29 | data[0] = getData(1); 30 | data[1] = getData(2); 31 | 32 | return _multi.call(addr, data); 33 | } 34 | } -------------------------------------------------------------------------------- /contracts/business_template/health_Record/Auth.sol: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * */ 16 | pragma solidity ^0.4.25; 17 | 18 | contract Auth{ 19 | address public owner; 20 | 21 | constructor() public { 22 | owner = msg.sender; 23 | } 24 | 25 | modifier onlyOwner() { 26 | require(msg.sender == owner,"Not admin"); 27 | _; 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /docs/data_structure/DataTable.md: -------------------------------------------------------------------------------- 1 | # DataTable.sol 2 | 3 | DataTable提供了基于bytes32主键的二维表、自定义类型值的可迭代、可查询的映射. 4 | 5 | ## 使用方法 6 | 7 | 首先需要通过import引入DataTable合约,然后通过"."进行方法调用,如下为调用例子: 8 | 9 | ``` 10 | 示例合约 StudentsGradesDemo.sol 11 | ``` 12 | 13 | 14 | ## API列表 15 | 16 | 编号 | API | API描述 17 | ---|---|--- 18 | 1 | *function insertItem(bytes32 rowId, bytes32 colId, DataItem item) public* | 新增数据项 19 | 2 | *ffunction getItem(bytes32 rowId, bytes32 colId) public view returns(DataItem)* |获取数据项 20 | 3 | *function getRow(bytes32 rowId) public view returns(DataRow)* |获得数据行 21 | 4 | *function isExists(bytes32 rowId, bytes32 colId) public view returns(bool)* |判断数据项是否存在 22 | 5 | *function isExists(bytes32 rowId) public view returns(bool)* |判断行是否存在 23 | 6 | *function rowCount()public view returns(uint256)* |获取行数 24 | 7 | *function iterate_start() public view returns(Pair)* | 枚举key的游标 25 | 8 | *function can_iterate(Pair iter) public view returns(bool)* | 游标是否可用 26 | 9 | *function iterate_next(Pair iter) public view returns(Pair)* | 下一个游标值 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /contracts/common_tools/history-query/HistoryQuery.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | /// @author tianlan 3 | 4 | pragma solidity >=0.8.0; 5 | 6 | contract HistoryQuery { 7 | uint public _value; 8 | mapping(uint => uint) public _historyValue; 9 | 10 | function setValue(uint value) external { 11 | uint prevValue = _historyValue[block.number]; 12 | _value = value; 13 | _historyValue[block.number] = prevValue; 14 | } 15 | 16 | function getValue(uint blockNumber) external view returns (uint) { 17 | uint low = 0; 18 | uint high = block.number; 19 | 20 | while (low <= high) { 21 | uint mid = (low + high) / 2; 22 | if (mid == blockNumber) { 23 | return _historyValue[mid]; 24 | } else if (mid < blockNumber) { 25 | low = mid + 1; 26 | } else { 27 | high = mid - 1; 28 | } 29 | } 30 | 31 | return _historyValue[blockNumber]; 32 | } 33 | } 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /contracts/business_template/Medicine/SpringToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.21; 2 | 3 | import "./StandardToken.sol"; 4 | import "./Ownable.sol"; 5 | 6 | /** 7 | * @title SpringToken 8 | * @dev ERC20 Token, where all tokens are pre-assigned to the creator. 9 | * Note they can later distribute these tokens as they wish using `transfer` and other 10 | * `StandardToken` functions. 11 | */ 12 | contract SpringToken is StandardToken, Ownable { 13 | 14 | string public constant name = "SpringToken"; // solium-disable-line uppercase 15 | string public constant symbol = "SPT"; // solium-disable-line uppercase 16 | uint8 public constant decimals = 18; // solium-disable-line uppercase 17 | 18 | uint256 public constant INITIAL_SUPPLY = 10000 * (10 ** uint256(decimals)); 19 | 20 | /** 21 | * @dev Constructor that gives msg.sender all of existing tokens. 22 | */ 23 | constructor() public { 24 | totalSupply_ = INITIAL_SUPPLY; 25 | balances[msg.sender] = INITIAL_SUPPLY; 26 | emit Transfer(0x0, msg.sender, INITIAL_SUPPLY); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /docs/common_tools/CloneFactory.md: -------------------------------------------------------------------------------- 1 | ## 说明 2 | 如果我们正要部署相同的合约,合约的每个实例都将具有相同的字节码。因此,每个部署存储所有字节码会反复促进字节码的 gas 成本浪费。 3 | 4 | 对此的解决方案是:只部署一个合约实例原型,让所有其他合约实例原型充当代理,将调用委托给合约的第一个实例原型,并允许函数在代理合约的上下文中运行。这样,合约的每个实例原型都会有自己的状态,并且只需将我们建立的合约实例用作原型库即可。 5 | 6 | > 这个示例是克隆多方投票治理合约,通过业务工厂合约创建多方投票治理合约,当然其他业务也可以用这种方式,比如根据某个积分合约克隆出不同的积分合约等等。 7 | 8 | ## 使用 9 | > 我们将部署原型合约、克隆工厂合约、业务工厂合约 10 | > 原型合约参考:多方投票治理合约 Ballot.sol 11 | - 部署原型合约 12 | - 部署克隆工厂合约 13 | - 部署业务工厂合约 14 | 15 | ## 属性 16 | - _CLONE_FACTORY_: 克隆工厂合约地址 17 | - _BALLOT_TEMPLATE_: 原型合约地址 18 | 19 | ## 接口 20 | - constructor(address cloneFactory, address ballotTemplate): 创建业务工厂合约 21 | - createBallot(bytes32 _subjectName, bytes32[] memory _proposalNames): 创建一个新的投票合约,并返回新的投票合约的地址。 22 | - updateBallotTemplate(address newBallotTemplate): 管理员操作更新原型合约地址 23 | 24 | ## 示例 25 | > 原型合约 Ballot.sol 得到合约地址 26 | > 部署克隆工厂合约 CloneFactory.sol 得到合约地址 27 | > 部署业务工厂合约 BallotFactory.sol 得到合约地址 28 | 29 | 1. 部署 `BallotFactory.sol` 传入 `克隆工厂合约地址`, `原型合约地址` 30 | 31 | 2. 调用 `createBallot` 传入投票合约的基本信息来创建一个新的投票合约,并返回新的投票合约的地址。 32 | 33 | 3. 可以调用 `updateBallotTemplate` 来更新原型合约地址 34 | 35 | 4. ... 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### common ### 2 | log/ 3 | src/main/resources 4 | src/test/resources 5 | 6 | ### gradle ### 7 | .gradle/ 8 | build 9 | dist/ 10 | 11 | ### mac ### 12 | .DS_Store 13 | 14 | ## eclipse ## 15 | .classpath 16 | .project 17 | .settings 18 | bin/ 19 | out/ 20 | conf/ 21 | 22 | ## integration test files 23 | nodes/ 24 | src/integration-test/resources/ 25 | build_chain.sh 26 | 27 | ### STS ### 28 | .apt_generated 29 | .factorypath 30 | .springBeans 31 | .sts4-cache 32 | 33 | ### IntelliJ IDEA ### 34 | .idea 35 | *.iws 36 | *.iml 37 | *.ipr 38 | 39 | ### NetBeans ### 40 | /nbproject/private/ 41 | /build/ 42 | /nbbuild/ 43 | /dist/ 44 | /nbdist/ 45 | /.nb-gradle/ 46 | 47 | ### Compiled class file ### 48 | *.class 49 | 50 | ### Log file ### 51 | *.log 52 | 53 | ### BlueJ files ### 54 | *.ctxt 55 | 56 | ### Mobile Tools for Java (J2ME) ### 57 | .mtj.tmp/ 58 | 59 | ### Package Files ### 60 | *.jar 61 | *.war 62 | *.nar 63 | *.ear 64 | *.zip 65 | *.tar.gz 66 | *.rar 67 | 68 | ### virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml ### 69 | hs_err_pid* 70 | 71 | ### repo ### 72 | -------------------------------------------------------------------------------- /contracts/common_tools/role/RBAC/Example.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.6.10; 2 | 3 | import "./Ownable.sol"; 4 | import "./RBAC.sol"; 5 | 6 | /** 7 | * @author SomeJoker 8 | * @title 例子 9 | */ 10 | contract Example is Ownable,RBAC{ 11 | string constant private ADD = "ADD"; 12 | string constant private SUB = "SUB"; 13 | string constant private MUL = "MUL"; 14 | string constant private DIV = "DIV"; 15 | 16 | function setRole(address addr,string memory _role) public onlyOwner{ 17 | addRole(addr, _role); 18 | } 19 | 20 | function resetRole(address addr,string memory _role) public onlyOwner{ 21 | removeRole(addr, _role); 22 | } 23 | 24 | function add(uint a,uint b) public view onlyRole(ADD) returns(uint){ 25 | return a+b; 26 | } 27 | 28 | function sub(uint a,uint b) public view onlyRole(SUB) returns(uint){ 29 | return a-b; 30 | } 31 | 32 | function mul(uint a,uint b) public view onlyRole(MUL) returns(uint){ 33 | return a*b; 34 | } 35 | 36 | function div(uint a,uint b) public view onlyRole(DIV) returns(uint){ 37 | return a/b; 38 | } 39 | 40 | 41 | } -------------------------------------------------------------------------------- /contracts/default/crypto/LibDecode.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | library LibDocode { 3 | function decode(bytes signHash, bytes signedString) internal returns (address){ 4 | bytes32 r = bytesToBytes32(slice(signedString, 0, 32)); 5 | bytes32 s = bytesToBytes32(slice(signedString, 32, 32)); 6 | byte v = slice(signedString, 64, 1)[0]; 7 | bytes32 hash = bytesToBytes32(slice(signHash, 0, 32)); 8 | return ecrecoverDecode(hash,r, s, v); 9 | } 10 | function slice(bytes memory data, uint start, uint len) internal returns (bytes){ 11 | bytes memory b = new bytes(len); 12 | 13 | for(uint i = 0; i < len; i++){ 14 | b[i] = data[i + start]; 15 | } 16 | 17 | return b; 18 | } 19 | function ecrecoverDecode(bytes32 hash, bytes32 r, bytes32 s, byte v1) internal returns (address addr){ 20 | uint8 v = uint8(v1) + 27; 21 | addr = ecrecover(hash, v, r, s); 22 | } 23 | function bytesToBytes32(bytes memory source) internal returns (bytes32 result) { 24 | assembly { 25 | result := mload(add(source, 32)) 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /docs/common_tools/white_list_manage.md: -------------------------------------------------------------------------------- 1 | ## 功能说明 2 | 本合约支持白名单管理,包含增删改查相关操作。 3 | 4 | ## 接口 5 | 提供了三个合约:SafeRole 合约,WhitelistAdminRole 合约,WhitelistedRole 合约。其中SafeRole是库合约,WhitelistedRole合约是对外服务合约,用于数据和逻辑抽象化。 6 | WhitelistedRole合约:对外服务的唯一接口。包含: 7 | - addWhitelistAdmin(address account):添加白名单管理员账户,amount是角色的地址 8 | - addWhitelisted(address account): 添加白名单账户,amount是角色的地址 9 | - isWhitelistAdmin(address account): 判断是否是白名单管理员,amount是角色的地址 10 | - isWhitelisted(address account): 判断账户是否在白名单里,amount是角色的地址 11 | - removeWhitelisted(address account): 移除白名单管理员账户,amount是角色的地址 12 | - renounceWhitelisted(): 清空白名单列表 13 | - renounceWhitelistAdmin(): 清空白名单管理员列表 14 | 15 | 16 | ## 使用示例 17 | 白名单管理的增删改查,整个过程如下: 18 | 19 | 合约初始化: 20 | 21 | - 部署WhitelistedRole合约 22 | 23 | 合约调用: 24 | 25 | - 调用WhitelistedRole.addWhitelistAdmin 提交添加白名单管理员 26 | - 调用WhitelistedRole.addWhitelisted 提交添加用户到白名单列表 27 | - 调用WhitelistedRole.isWhitelistAdmin 判断是否是白名单管理员 28 | - 调用WhitelistedRole.isWhitelisted 判断是否在白名单列表 29 | - 调用WhitelistedRole.removeWhitelisted 移除白名单 30 | - 调用WhitelistedRole.renounceWhitelisted 清空白名单列表 31 | - 调用WhitelistedRole.renounceWhitelistAdmin 清空白名单管理员列表 32 | -------------------------------------------------------------------------------- /contracts/common_tools/timelock/Ownable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.6.10; 2 | 3 | contract Ownable { 4 | address private _owner; 5 | 6 | event NewAdmin(address newAdmin); 7 | 8 | /** 9 | * @dev The Ownable constructor sets the original `owner` of the contract to the sender 10 | * account. 11 | */ 12 | constructor () internal { 13 | _owner = msg.sender; 14 | emit NewAdmin(_owner); 15 | } 16 | 17 | /** 18 | * @return the address of the owner. 19 | */ 20 | function owner() public view returns (address) { 21 | return _owner; 22 | } 23 | 24 | /** 25 | * @dev Throws if called by any account other than the owner. 26 | */ 27 | modifier onlyOwner() { 28 | require(isOwner(), "Ownable: not authorized"); 29 | _; 30 | } 31 | 32 | /** 33 | * @return true if `msg.sender` is the owner of the contract. 34 | */ 35 | function isOwner() public view returns (bool) { 36 | return msg.sender == _owner; 37 | } 38 | 39 | function changeAdmin(address newAdmin) public onlyOwner{ 40 | _owner = newAdmin; 41 | emit NewAdmin(newAdmin); 42 | } 43 | } -------------------------------------------------------------------------------- /contracts/business_template/bill/utils/Console.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | //通过log函数重载,对不同类型的变量trigger不同的event,实现solidity打印效果,使用方法为:log(string name, var value) 4 | contract Console { 5 | 6 | event LogString(string, string); 7 | function log(string s , string x) internal { 8 | emit LogString(s, x); 9 | } 10 | 11 | event LogUint(string, uint); 12 | function log(string s , uint x) internal { 13 | emit LogUint(s, x); 14 | } 15 | 16 | event LogInt(string, int); 17 | function log(string s , int x) internal { 18 | emit LogInt(s, x); 19 | } 20 | 21 | event LogBytes(string, bytes); 22 | function log(string s , bytes x) internal { 23 | emit LogBytes(s, x); 24 | } 25 | 26 | event LogBytes32(string, bytes32); 27 | function log(string s , bytes32 x) internal { 28 | emit LogBytes32(s, x); 29 | } 30 | 31 | event LogAddress(string, address); 32 | function log(string s , address x) internal { 33 | emit LogAddress(s, x); 34 | } 35 | 36 | event LogBool(string, bool); 37 | function log(string s , bool x) internal { 38 | emit LogBool(s, x); 39 | } 40 | } -------------------------------------------------------------------------------- /contracts/business_template/chattel/utils/Console.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | //通过log函数重载,对不同类型的变量trigger不同的event,实现solidity打印效果,使用方法为:log(string name, var value) 4 | contract Console { 5 | 6 | event LogString(string, string); 7 | function log(string s , string x) internal { 8 | emit LogString(s, x); 9 | } 10 | 11 | event LogUint(string, uint); 12 | function log(string s , uint x) internal { 13 | emit LogUint(s, x); 14 | } 15 | 16 | event LogInt(string, int); 17 | function log(string s , int x) internal { 18 | emit LogInt(s, x); 19 | } 20 | 21 | event LogBytes(string, bytes); 22 | function log(string s , bytes x) internal { 23 | emit LogBytes(s, x); 24 | } 25 | 26 | event LogBytes32(string, bytes32); 27 | function log(string s , bytes32 x) internal { 28 | emit LogBytes32(s, x); 29 | } 30 | 31 | event LogAddress(string, address); 32 | function log(string s , address x) internal { 33 | emit LogAddress(s, x); 34 | } 35 | 36 | event LogBool(string, bool); 37 | function log(string s , bool x) internal { 38 | emit LogBool(s, x); 39 | } 40 | } -------------------------------------------------------------------------------- /contracts/common_tools/clone/CloneFactory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | /// @author Steve Jin 3 | 4 | pragma solidity >=0.8.0; 5 | pragma experimental ABIEncoderV2; 6 | 7 | // 定义接口ICloneFactory 8 | interface ICloneFactory { 9 | // 定义接口方法clone,传入原型合约地址,克隆传入的原型合约,返回新合约地址 10 | function clone(address prototype) external returns (address proxy); 11 | } 12 | 13 | // 实现接口 14 | contract CloneFactory is ICloneFactory { 15 | // 实现接口方法,该方法内部使用 Solidity 的汇编语言实现了合约原型的克隆功能。具体来说,它首先将合约原型的地址转换为 20 字节的字节数组 bytes20,然后使用汇编代码创建一个新合约。创建合约的代码通过将字节数组中的地址插入到一个预先定义的字节码中来实现。 16 | function clone(address prototype) external override returns (address proxy) { 17 | bytes20 targetBytes = bytes20(prototype); 18 | assembly { 19 | let clone := mload(0x40) 20 | mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) 21 | mstore(add(clone, 0x14), targetBytes) 22 | mstore( 23 | add(clone, 0x28), 24 | 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000 25 | ) 26 | proxy := create(0, clone, 0x37) 27 | } 28 | return proxy; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /contracts/common_tools/role/RBAC/RBAC.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.6.10; 2 | import "./Roles.sol"; 3 | 4 | /** 5 | * @author SomeJoker 6 | * @title RBAC 7 | */ 8 | contract RBAC{ 9 | using Roles for Roles.Role; 10 | 11 | mapping (string => Roles.Role) private roles; 12 | 13 | event RoleAdded(address indexed operater,string role); 14 | event RoleRemoved(address indexed operater,string role); 15 | 16 | function addRole(address _operater, string memory _role) internal{ 17 | roles[_role].addRole(_operater); 18 | emit RoleAdded(_operater,_role); 19 | } 20 | 21 | function removeRole(address _operater, string memory _role) internal{ 22 | roles[_role].removeRole(_operater); 23 | emit RoleRemoved(_operater,_role); 24 | } 25 | 26 | function hasRole(address _operater, string memory _role) public view returns(bool){ 27 | return roles[_role].hasRole(_operater); 28 | } 29 | 30 | function checkRole(address _operater, string memory _role) public view{ 31 | roles[_role].checkRole(_operater); 32 | } 33 | 34 | modifier onlyRole(string memory _role){ 35 | checkRole(msg.sender, _role); 36 | _; 37 | } 38 | } -------------------------------------------------------------------------------- /contracts/business_template/reward_point/LibSafeMath.sol: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * */ 16 | 17 | pragma solidity ^0.4.25; 18 | 19 | 20 | library LibSafeMath { 21 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 22 | require(b <= a, "SafeMath: subtraction overflow"); 23 | uint256 c = a - b; 24 | 25 | return c; 26 | } 27 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 28 | uint256 c = a + b; 29 | require(c >= a, "SafeMath: addition overflow"); 30 | 31 | return c; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /contracts/business_template/CarbonSystemManager/Ownable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | 4 | contract Ownable { 5 | // 定义角色枚举类型 6 | enum Role { Enterprise, Regulator } 7 | 8 | uint256 internal constant TOTAL_EMISSION = 1000; 9 | // 默认按照100元一个碳额度 10 | uint256 internal constant EXCESS_BALANCE = 3; 11 | bool internal constant AUDIT_SUCCESS = true; 12 | bool internal constant AUDIT_FAILED = false; 13 | 14 | // 企业账户的事件 15 | event RegisterAccount(address indexed _acount,string indexed _name); 16 | // 上传审核的事件 17 | event UploadQualification(address indexed _acount,string indexed _name,string indexed _content); 18 | // 审批企业申请的事件 19 | event VerifyQualification(address indexed _enterpriseAddr,uint256 indexed _emissionLimit); 20 | // 交易碳额度 21 | event TransferEmissionLimit(address indexed _from,address indexed _to,uint256 indexed _amount); 22 | // 出售碳额度 23 | event SellEmissionLimit(uint256 indexed _emissionLimitCount,uint256 indexed _amount); 24 | // 更新企业账户的余额 25 | event UpdateBalnce(address indexed _enterpriseAddr,uint256 indexed _amount); 26 | // 更新企业账户的碳排放额度 27 | event UpdateEmissionLimit(address indexed _enterpriseAddr,uint256 indexed _emissionLimit); 28 | } -------------------------------------------------------------------------------- /contracts/business_template/Medicine/TokenDestructible.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.21; 2 | 3 | import "./Ownable.sol"; 4 | import "./ERC20Basic.sol"; 5 | 6 | 7 | /** 8 | * @title TokenDestructible: 9 | * @author Remco Bloemen 10 | * @dev Base contract that can be destroyed by owner. All funds in contract including 11 | * listed tokens will be sent to the owner. 12 | */ 13 | contract TokenDestructible is Ownable { 14 | 15 | constructor() public payable { } 16 | 17 | /** 18 | * @notice Terminate contract and refund to owner 19 | * @param tokens List of addresses of ERC20 or ERC20Basic token contracts to 20 | refund. 21 | * @notice The called token contracts could try to re-enter this contract. Only 22 | supply token contracts you trust. 23 | */ 24 | function destroy(address[] tokens) onlyOwner public { 25 | // Transfer tokens to owner 26 | for (uint256 i = 0; i < tokens.length; i++) { 27 | ERC20Basic token = ERC20Basic(tokens[i]); 28 | uint256 balance = token.balanceOf(this); 29 | token.transfer(owner, balance); 30 | } 31 | // Transfer Eth to owner and terminate contract 32 | selfdestruct(owner); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /contracts/common_tools/history_snapshot/HistorySnapshotV2Demo.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.4.25; 3 | pragma experimental ABIEncoderV2; 4 | 5 | import "./HistorySnapshotV2.sol"; 6 | /** 7 | * @dev 历史状态快照合约测试demo 8 | */ 9 | contract HistorySnapshotV2Demo{ 10 | HistorySnapshotV2 private historySnapshotV2; 11 | 12 | //以string类型为例 13 | function test() returns (string memory value1, string memory value2, uint256[] memory blockNumbers, string[] memory values){ 14 | historySnapshotV2 = new HistorySnapshotV2; 15 | 16 | // updateString1(); 17 | value1 = historySnapshotV2.getString("test", 0); 18 | // 此时value1应该为hello 19 | // updateString2(); 20 | value1 = historySnapshotV2.getString("test", 0); 21 | // 此时value1应该为world 22 | (blockNumbers, values) = historySnapshotV2.getStringHistory("test"); 23 | // blockNumbers应该为[num1, num2] 其中num1和num2为调用updateString1()、updateString2()时的块号 24 | // values应该为["hello", "world"] 25 | } 26 | 27 | function updateString1() public { 28 | historySnapshotV2.updateString("test", "hello"); 29 | } 30 | function updateString2() public { 31 | historySnapshotV2.updateString("test", "world"); 32 | } 33 | } -------------------------------------------------------------------------------- /docs/base_type/LibAscii.md: -------------------------------------------------------------------------------- 1 | # LibAscii.sol 2 | 3 | LibAscii 提供ascii与字符串之间的转换 4 | 5 | 6 | ## 函数说明 7 | 1. decAscii2str(string memory data):10进制ascii转字符串 8 | - data:10进制ascii字符串 0至127 9 | 10 | 2. hexAscii2str(string memory data):16进制ascii转字符串 11 | - data:16进制ascii字符串 00至7f(不限大小写) 12 | 13 | 3. str2ascii(string memory ascii):ascii字符串转10进制字符串 14 | - ascii:ascii字符串 15 | 16 | ## 使用方法 17 | 18 | ``` 19 | pragma solidity ^0.4.25; 20 | 21 | import "./LibAscii.sol"; 22 | 23 | contract LibAsciiTest{ 24 | 25 | function ascii2str() public pure returns(string,string,string,string){ 26 | //10进制ascii转字符串 27 | string memory result= LibAscii.decAscii2str("55"); 28 | //result:"7" 29 | string memory result1= LibAscii.decAscii2str("109"); 30 | //result:"m" 31 | 32 | //16进制ascii转字符串 33 | string memory result2= LibAscii.hexAscii2str("37"); 34 | //result1:"7" 35 | string memory result3= LibAscii.hexAscii2str("6D"); 36 | //result1:"m" 37 | 38 | return (result,result1,result2,result3); 39 | } 40 | 41 | function str2ascii() public pure returns(string){ 42 | string memory result=LibAscii.str2ascii("Zz"); 43 | //result:"90122" 44 | return result; 45 | } 46 | } 47 | 48 | ``` -------------------------------------------------------------------------------- /contracts/business_template/Medicine/Ownable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.21; 2 | 3 | /** 4 | * @title Ownable 5 | * @dev The Ownable contract has an owner address, and provides basic authorization control 6 | * functions, this simplifies the implementation of "user permissions". 7 | */ 8 | contract Ownable { 9 | address public owner; 10 | 11 | 12 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 13 | 14 | 15 | /** 16 | * @dev The Ownable constructor sets the original `owner` of the contract to the sender 17 | * account. 18 | */ 19 | constructor() public { 20 | owner = msg.sender; 21 | } 22 | 23 | /** 24 | * @dev Throws if called by any account other than the owner. 25 | */ 26 | modifier onlyOwner() { 27 | require(msg.sender == owner); 28 | _; 29 | } 30 | 31 | /** 32 | * @dev Allows the current owner to transfer control of the contract to a newOwner. 33 | * @param newOwner The address to transfer ownership to. 34 | */ 35 | function transferOwnership(address newOwner) public onlyOwner { 36 | require(newOwner != address(0)); 37 | emit OwnershipTransferred(owner, newOwner); 38 | owner = newOwner; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /docs/common_tools/RoleOperation.md: -------------------------------------------------------------------------------- 1 | ## 功能说明 2 | 3 | 本合约支持角色操作。包含角色的增丶删丶改丶查: 4 | 5 | ## 接口 6 | 7 | 提供了两个合约:Roles合约,Character合约。其中Character合约是对外服务合约,Roles合约是库合约,用于数据和逻辑抽象化。 8 | 9 | Character合约:对外服务的唯一接口。包含: 10 | - addCharacter(address amount,string _summary): 管理员进行添加角色操作。amount是添加角色的地址,_ _summary添加角色的基本信息 11 | - removeCharacter(address amount): 管理员进行删除角色操作。amount是删除角色的地址 12 | - reviseCharacter(address amount,string _summary):管理员进行修改角色信息操作。amount是修改角色的地址, _summary修改角色的基本信息 13 | - seekCharacter(address amount): 任何人都可以进行查询角色信息操作。amount是查询角色的地址 14 | - getAllCharater():任何人都可以进行查看当前存在的所有角色操作。 15 | - isCharacter(address amount): 任何人都可以进行查看当前地址是否已经被添加为角色。amount是查询的地址 16 | 17 | ## 使用示例 18 | 19 | 角色的增删改查,整个过程如下: 20 | 21 | 合约初始化: 22 | 23 | - 以管理员地址部署Character合约 24 | 25 | 合约调用: 26 | 27 | - 管理员调用Character.addCharacter提交添加角色请求,参数传入添加角色的地址,角色的基本信息 28 | - 任何人调用Character.getAllCharater提交查看角色请求 29 | - 任何人调用Character.isCharacter提交查询当前地址是否已经被添加成功 30 | - 管理员调用Character.reviseCharacter提交修改角色信息请求,参数传入修改角色的地址,修改角色的基本信息 31 | - 任何人调用Character.seekCharacter提交查询角色信息请求,参数传入查询角色的地址 32 | - 管理员调用Character.removeCharacter提交删除角色的请求,参数传入删除角色的地址 33 | - 任何人调用Character.isCharacter提交查询角色是否还存在请求,参数传入查询角色的地址 34 | - 任何人调用Character.getAllCharater提交查看角色请求 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /contracts/common_tools/proxy/MinimalProxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.6.10; 3 | 4 | contract MinimalProxy { 5 | 6 | // @title createClone 创建代理合约 7 | // @param `implementation` 主合约地址 8 | // 9 | // @dev MinimalProxy 利用了 `delegatecall` 提供了一种节省部署成本的合约复制方案 10 | // 当合约中存在多个代理合约和一个逻辑合约时,每个代理合约存储对应的数据, 11 | // 所有代理合约共享单个逻辑合约的执行逻辑。 12 | function createClone(address implementation) internal returns(address instance) { 13 | assembly { 14 | // 加载空闲内存指针 15 | let ptr := mload(0x40) 16 | // 关于固定字节码,参考 https://blog.openzeppelin.com/deep-dive-into-the-minimal-proxy-contract/ 17 | // 在ptr中,将构造函数字节码存入指针打包 18 | mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) 19 | // 在ptr+20字节位置,将地址左移12个字节得到原始地址并存入指针打包 20 | mstore(add(ptr, 0x14), shl(0x60, implementation)) 21 | // 在ptr+40字节位置,将0x5af4...存入指针打包 22 | mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) 23 | // 创建合约实例 24 | instance := create(0, ptr, 0x37) 25 | } 26 | // 验证合约是否创建成功 27 | require(instance != address(0), "MinimalProxy: create failed"); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /contracts/business_template/marriage_evidence/Roles.sol: -------------------------------------------------------------------------------- 1 | pragma solidity^0.4.25; 2 | 3 | library Roles{ 4 | struct Role{ 5 | mapping(address=>bool) bearer; 6 | mapping(address=>string) summary; 7 | } 8 | //判断角色 9 | function has(Role storage role,address amount)internal view returns(bool){ 10 | require(amount!=address(0),"Address is zero address"); 11 | return role.bearer[amount]; 12 | } 13 | //添加角色 14 | function add(Role storage role,address amount,string _summary)internal{ 15 | require(!has(role,amount),"Address already exists"); 16 | role.bearer[amount] = true; 17 | role.summary[amount] = _summary; 18 | } 19 | //删除角色 20 | function remove(Role storage role,address amount)internal{ 21 | require(has(role,amount),"Address does not exist"); 22 | role.bearer[amount] = false; 23 | } 24 | //修改角色 25 | function revise(Role storage role,address amount,string _summary)internal { 26 | require(has(role,amount),"Address does not exist"); 27 | role.summary[amount] = _summary; 28 | } 29 | //查询角色 30 | function seek(Role storage role,address amount)internal view returns(string){ 31 | require(has(role,amount),"Address does not exist"); 32 | return role.summary[amount]; 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /contracts/common_tools/role/role_operation/Roles.sol: -------------------------------------------------------------------------------- 1 | pragma solidity^0.4.25; 2 | 3 | library Roles{ 4 | struct Role{ 5 | mapping(address=>bool) bearer; 6 | mapping(address=>string) summary; 7 | } 8 | //判断角色 9 | function has(Role storage role,address amount)internal view returns(bool){ 10 | require(amount!=address(0),"Address is zero address"); 11 | return role.bearer[amount]; 12 | } 13 | //添加角色 14 | function add(Role storage role,address amount,string _summary)internal{ 15 | require(!has(role,amount),"Address already exists"); 16 | role.bearer[amount] = true; 17 | role.summary[amount] = _summary; 18 | } 19 | //删除角色 20 | function remove(Role storage role,address amount)internal{ 21 | require(has(role,amount),"Address does not exist"); 22 | role.bearer[amount] = false; 23 | } 24 | //修改角色 25 | function revise(Role storage role,address amount,string _summary)internal { 26 | require(has(role,amount),"Address does not exist"); 27 | role.summary[amount] = _summary; 28 | } 29 | //查询角色 30 | function seek(Role storage role,address amount)internal view returns(string){ 31 | require(has(role,amount),"Address does not exist"); 32 | return role.summary[amount]; 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /docs/business_template/Traceability.md: -------------------------------------------------------------------------------- 1 | ## 商品溯源 2 | 3 | 产品溯源是将当前先进的物联网技术、自动控制技术、自动识别技术、互联网技术结合利用,通过专业的机器设备对单件产品赋予唯一的一维码或者二维码作为防伪身份证,实现“一物一码”,然后可对产品的生产、仓储、分销、物流运输、市场稽查、销售终端等各个环节采集数据并追踪,构成产品的生产、仓储、销售、流通和服务的一个全生命周期管理 4 | 5 | 6 | 7 | ## 接口 8 | 9 | 提供了三个合约:TraceabilityFactory合约,Traceability合约,Goods合约。 10 | 11 | TraceabilityFactory合约:对外服务的唯一接口。包含: 12 | 13 | - createTraceability(bytes32 goodsGroup): 创建溯源商品类,goodsGroup: 为商品类hash码 14 | - createTraceGoods(bytes32 goodsGroup, uint64 goodsId): 创建需要溯源的商品,goodsId:唯一标识商品的Id 15 | - changeTraceGoods(bytes32 goodsGroup, uint64 goodsId, int16 goodsStatus, string remark):商品状态改变,goodsStatus:商品流转的每一个环节可以用一个状态进行标识,remark:状态变更的摘要信息 16 | - getStatus(bytes32 goodsGroup, uint64 goodsId): 获取商品的当前状态 17 | - getTraceInfo(bytes32 goodsGroup, uint64 goodsId) :获取商品的全流程信息,包括每一个环节的状态、时间、操作员、摘要信息 18 | - getGoodsGroup(string memory name):计算商品种类的哈希值,name:商品标识或名称 19 | ## 使用示例 20 | 21 | 22 | 合约调用: 23 | 24 | - 获取商品分析哈希值 goodsGroup = getGoodsGroup("商品标识") 25 | - 创建自己的溯源商品类 createTraceability(goodsGroup) 26 | - 在商品类下创建商品 createTraceGoods(goodsGroup, "100000001") 27 | - 商品状态变更 changeTraceGoods(goodsGroup, "100000001", 1, "环节信息") 28 | - 查询商品的当前状态 getStatus(goodsGroup, "100000001") 29 | - 查询商品的全流程信息 getTraceInfo(goodsGroup, "100000001") 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /contracts/business_template/traceability/Goods.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | pragma experimental ABIEncoderV2; 3 | 4 | contract Goods{ 5 | struct TraceData{ 6 | address addr; //Operator address 7 | int16 status; //goods status 8 | uint timestamp; //Operator time 9 | string remark; //Digested Data 10 | } 11 | uint64 _goodsId; 12 | int16 _status; //current status 13 | TraceData[] _traceData; 14 | 15 | event newStatus( address addr, int16 status, uint timestamp, string remark); 16 | 17 | constructor(uint64 goodsId) public{ 18 | _goodsId = goodsId; 19 | _traceData.push(TraceData({addr:tx.origin, status:0, timestamp:now, remark:"create"})); 20 | emit newStatus(tx.origin, 0, now, "create"); 21 | } 22 | 23 | function changeStatus(int16 goodsStatus, string memory remark) public { 24 | _status = goodsStatus; 25 | _traceData.push(TraceData({addr:tx.origin, status:goodsStatus, timestamp:now, remark:remark})); 26 | emit newStatus(tx.origin, goodsStatus, now, remark); 27 | } 28 | 29 | function getStatus()public view returns(int16){ 30 | return _status; 31 | } 32 | 33 | function getTraceInfo()public view returns(TraceData[] memory _data){ 34 | return _traceData; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /docs/common_tools/gm.md: -------------------------------------------------------------------------------- 1 | # FISCO BCOS 国密算法使用的工具和示例合约 2 | 3 | 4 | > 本示例是通过 FISCO BCOS 的预编译合约实现.https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/manual/precompiled_contract.html 5 | > 通过 ICrypto.sol 文件声明需要调用的预编译合约接口 6 | > 通过 `ICrypto constant Crypto = ICrypto(address(0x5006))` 完成接口的注册和使用 7 | > 8 | > 注意: **0x5006** 为地址空间,必须唯一 9 | 10 | ## 示例合约 11 | ````solidity 12 | pragma solidity ^0.5.0; 13 | 14 | // 导入预编译合约 15 | import "./ICrypto.sol"; 16 | 17 | contract HelloWorld{ 18 | 19 | bytes32 hashVal; 20 | 21 | ICrypto constant Crypto = ICrypto(address(0x5006)); 22 | 23 | /** 24 | * @return 获取 _message 的哈希 25 | **/ 26 | function getMeessgeHash() view public returns(bytes32) { 27 | return hashVal; 28 | } 29 | 30 | /** 31 | * @notice 使用 Keccak-256 计算 _message 哈希 32 | * @param _message 需要计算哈希的参数 33 | **/ 34 | function keccak256Hash(string memory _message) public returns(bool){ 35 | 36 | hashVal = Crypto.keccak256Hash(bytes(_message)); 37 | return true; 38 | } 39 | 40 | /** 41 | * @notice 使用国密算法 SM3 计算 _message 哈希 42 | * @param _message 需要计算哈希的参数 43 | **/ 44 | function sm3Hash(string memory _message) public returns (bool) { 45 | 46 | hashVal = Crypto.sm3(bytes(_message)); 47 | return true; 48 | } 49 | } 50 | ```` -------------------------------------------------------------------------------- /contracts/business_template/evidence/Authentication.sol: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * */ 16 | 17 | pragma solidity ^0.4.25; 18 | 19 | contract Authentication{ 20 | address public _owner; 21 | mapping(address=>bool) private _acl; 22 | 23 | constructor() public{ 24 | _owner = msg.sender; 25 | } 26 | 27 | modifier onlyOwner(){ 28 | require(msg.sender == _owner, "Not admin"); 29 | _; 30 | } 31 | 32 | modifier auth(){ 33 | require(msg.sender == _owner || _acl[msg.sender]==true, "Not authenticated"); 34 | _; 35 | } 36 | 37 | function allow(address addr) public onlyOwner{ 38 | _acl[addr] = true; 39 | } 40 | 41 | function deny(address addr) public onlyOwner{ 42 | _acl[addr] = false; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /contracts/common_tools/counter/SimpleCounter.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.25; 2 | 3 | // Contract: SimpleCounter 4 | // Description: 5 | // inc/dec counter by val 6 | // safe inc and dec with maximum uint256 and minimum 0 7 | // Core Functions: 8 | // inc_val(uint x) -> (bool, uint): inc counter by x 9 | // dec_val(uint x) -> (bool, uint): dec counter by x 10 | // inc() -> (bool, uint): inc counter by 1 11 | // dec() -> (bool, uint): dec counter by 1 12 | 13 | contract SimpleCounter { 14 | uint256 counter = 0; 15 | uint256 MAXVAL = 1<<256-1; 16 | 17 | constructor() public { 18 | counter = 0; 19 | } 20 | 21 | function inc_val(uint x) public returns(bool, uint) { 22 | if (MAXVAL - counter >= x) { 23 | counter += x; 24 | return (true, counter); 25 | } 26 | return (false, counter); 27 | } 28 | 29 | function dec_val(uint x) public returns(bool, uint) { 30 | if (counter - x >= 0) { 31 | counter -= x; 32 | return (true, counter); 33 | } 34 | return (false, counter); 35 | } 36 | 37 | function inc() public returns(bool, uint) { 38 | return inc_val(1); 39 | } 40 | 41 | function dec() public returns(bool, uint) { 42 | return dec_val(1); 43 | } 44 | 45 | function get() public view returns(uint) { 46 | return counter; 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /contracts/business_template/reward_point/BasicAuth.sol: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * */ 16 | 17 | pragma solidity ^0.4.25; 18 | 19 | contract BasicAuth { 20 | address public _owner; 21 | 22 | constructor() public { 23 | _owner = msg.sender; 24 | } 25 | 26 | modifier onlyOwner() { 27 | require(auth(msg.sender), "Only owner!"); 28 | _; 29 | } 30 | 31 | function setOwner(address owner) 32 | public 33 | onlyOwner 34 | { 35 | _owner = owner; 36 | } 37 | 38 | function auth(address src) public view returns (bool) { 39 | if (src == address(this)) { 40 | return true; 41 | } else if (src == _owner) { 42 | return true; 43 | } else { 44 | return false; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /contracts/common_tools/role/white_list/WhitelistedRole.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | import "./SafeRole.sol"; 4 | import "./WhitelistAdminRole.sol"; 5 | 6 | 7 | contract WhitelistedRole is WhitelistAdminRole { 8 | using SafeRole for SafeRole.Role; 9 | 10 | event WhitelistedAdded(address indexed account); 11 | event WhitelistedRemoved(address indexed account); 12 | 13 | SafeRole.Role private _whitelisteds; 14 | 15 | modifier onlyWhitelisted() { 16 | require(isWhitelisted(msg.sender), "WhitelistedRole: caller does not have the Whitelisted role"); 17 | _; 18 | } 19 | 20 | function isWhitelisted(address account) public view returns (bool) { 21 | return _whitelisteds.has(account); 22 | } 23 | 24 | function addWhitelisted(address account) public onlyWhitelistAdmin { 25 | _addWhitelisted(account); 26 | } 27 | 28 | function removeWhitelisted(address account) public onlyWhitelistAdmin { 29 | _removeWhitelisted(account); 30 | } 31 | 32 | function renounceWhitelisted() public { 33 | _removeWhitelisted(msg.sender); 34 | } 35 | 36 | function _addWhitelisted(address account) internal { 37 | _whitelisteds.add(account); 38 | emit WhitelistedAdded(account); 39 | } 40 | 41 | function _removeWhitelisted(address account) internal { 42 | _whitelisteds.remove(account); 43 | emit WhitelistedRemoved(account); 44 | } 45 | } -------------------------------------------------------------------------------- /docs/common_tools/Ballot.md: -------------------------------------------------------------------------------- 1 | ## 说明 2 | 多方投票治理 3 | 4 | ## 使用 5 | > 多方投票治理合约 Ballot.sol 6 | - 部署合约 7 | - `constructor` 传入 `bytes32`, `bytes32[]` 8 | - bytes32: 主题名称 9 | - bytes32[]: 提案内容集 10 | - ... 11 | 12 | ## 属性 13 | - chairperson: 发起人 14 | - subjectName: 主题名称 15 | - voters: 投票人信息 16 | - uint weight: 投票权重 17 | - bool voted: 是否已投票 18 | - address delegate: 授权地址 19 | - uint vote: 提案的索引 20 | - proposals: 提案信息集合 21 | - bytes32 name: 提案名称 22 | - uint voteCount: 投票次数 23 | 24 | ## 接口 25 | - constructor(bytes32 _subjectName, bytes32[] memory _proposalNames): 创建提案合约 26 | - giveRightToVote(address _voter): 提案合约创建人给指定地址投票权限 27 | - delegate(address _ballot, address _to): 将指定提案合约的投票权授权给指定地址 28 | - vote(address _ballot, uint _proposal): 给指定提案投票 29 | - winningProposal(address _ballot): 返回指定提案合约的最多票数提案的索引 30 | - winnerName(address _ballot): 返回指定提案合约的最多票数提案的名称 31 | - getChairperson(): 获取发起人 32 | - getSubjectName(): 获取主题名称 33 | - getVoters(address _ballot, address _voter): 获取指定提案合约的投票人的信息 34 | - getProposalsLength(address _ballot): 获取指定提案合约的提案个数 35 | - getProposals(address _ballot, uint _proposalIndex): 获取指定提案合约的指定提案的信息 36 | 37 | ## 示例 38 | > 部署 Ballot.sol 39 | 40 | 1. 部署 `Ballot.sol` 传入 `主题名称`, `提案内容集` 41 | 42 | 2. 调用 `giveRightToVote` 添加新投票人 43 | 44 | 3. 可以调用 `delegate(address _ballot, address _to)` 将指定提案合约的投票权授权给指定地址 45 | 46 | 4. 可以调用 `vote(address _ballot, uint _proposal)` 给指定提案投票 47 | 48 | 4. 调用 `winnerName(address _ballot):` 获取指定提案合约的最多票数提案的名称 49 | 50 | 5. ... 51 | -------------------------------------------------------------------------------- /docs/default/internalFunction.md: -------------------------------------------------------------------------------- 1 | # solidity 内置函数转换 2 | 提供了一些内置函数的直接访问接口,主要包括block,tx相关 3 | 4 | ## API列表 5 | 6 | 编号 | API | API描述 7 | ---|---|--- 8 | 1 | *getBlockhash(uint256 blockNumber) view public returns(bytes32)* | 根据指定的区块号获取hash(仅支持最近256个区块,且不包含当前区块) 9 | 2 | *getBlockNumber() view public returns(address)* |获取当前区块的高度 10 | 3 | *getTimestamp() view public returns(uint256)* | 获取当前区块的时间戳 11 | 4 | *isContract(address addr) view public returns(bool)* | 判断一个地址是否是合约地址 12 | 5 | *getCodeByAddress(address addr) view public returns(bytes)* | 根据合约地址获取合约代码 13 | 6 | *computeAddress(bytes32 salt, bytes32 bytecodeHash) view public returns(address)* | 根据字节码计算合约的地址 14 | 15 | ## API 详情 16 | 17 | ### ***1. getBlockhash 函数*** 18 | 根据指定的区块号获取hash 19 | #### 参数 20 | - blockNumber: 区块高度 21 | #### 返回值 22 | - 区块的hash 23 | 24 | ### ***2. getBlockNumber 函数*** 25 | 获取当前区块的高度 26 | #### 参数 27 | - 无 28 | #### 返回值 29 | - 区块高度 30 | 31 | ### ***3. getTimestamp 函数*** 32 | 获取当前区块的时间戳 33 | #### 参数 34 | - 无 35 | #### 返回值 36 | - 当前区块的时间戳 37 | 38 | 39 | ### ***4. isContract 函数*** 40 | 验证一个地址是否是合约地址 41 | #### 参数 42 | - address: 待验证的地址 43 | #### 返回值 44 | - bool 45 | 46 | 47 | ### ***5. getCodeByAddress 函数*** 48 | 根据合约地址获取合约代码 49 | #### 参数 50 | - address: 合约地址 51 | #### 返回值 52 | - bytes: 字节码 53 | 54 | 55 | ### ***6. computeAddress 函数*** 56 | 根据字节码计算合约的地址, 对应一些通过creat2方法创建的合约,如果有其字节码和盐,那么可以得到其部署的合约地址 57 | #### 参数 58 | - bytes32: salt 59 | - bytes32: bytecodeHash 60 | #### 返回值 61 | - address: 合约地址 62 | -------------------------------------------------------------------------------- /contracts/business_template/Medicine/SafeMath.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.21; 2 | 3 | 4 | /** 5 | * @title SafeMath 6 | * @dev Math operations with safety checks that throw on error 7 | */ 8 | library SafeMath { 9 | 10 | /** 11 | * @dev Multiplies two numbers, throws on overflow. 12 | */ 13 | function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { 14 | if (a == 0) { 15 | return 0; 16 | } 17 | c = a * b; 18 | assert(c / a == b); 19 | return c; 20 | } 21 | 22 | /** 23 | * @dev Integer division of two numbers, truncating the quotient. 24 | */ 25 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 26 | // assert(b > 0); // Solidity automatically throws when dividing by 0 27 | // uint256 c = a / b; 28 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 29 | return a / b; 30 | } 31 | 32 | /** 33 | * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). 34 | */ 35 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 36 | assert(b <= a); 37 | return a - b; 38 | } 39 | 40 | /** 41 | * @dev Adds two numbers, throws on overflow. 42 | */ 43 | function add(uint256 a, uint256 b) internal pure returns (uint256 c) { 44 | c = a + b; 45 | assert(c >= a); 46 | return c; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /contracts/business_template/intellectualProperty/sol/RoyaltyManager.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | contract RoyaltyManager { 4 | 5 | struct Pricing { 6 | uint256 price;//售卖价格 7 | mapping(address => uint256) distribution;//每个参与者的分成,可以是百分比【需要业务端限制百分比,比如这里为10,标识10%】,也可以数值等其他设定 8 | } 9 | 10 | mapping(bytes32 => Pricing) public pricings; 11 | 12 | event PricingSet(bytes32 indexed workHash, uint256 price); 13 | event DistributionUpdated(bytes32 indexed workHash, address indexed participant, uint256 percentage); 14 | event PricingRevoked(bytes32 indexed workHash); 15 | 16 | modifier onlyWorkOwner(address workOwner) { 17 | require(tx.origin == workOwner, "只有作品拥有者可以进行操作"); 18 | _; 19 | } 20 | 21 | function setPricing(bytes32 workHash, address workOwner, uint256 price) public onlyWorkOwner(workOwner) { 22 | pricings[workHash].price = price; 23 | emit PricingSet(workHash, price); 24 | } 25 | //更新收益分配 26 | function updateDistribution(bytes32 workHash, address workOwner, address participant, uint256 percentage) public onlyWorkOwner(workOwner) { 27 | pricings[workHash].distribution[participant] = percentage; 28 | emit DistributionUpdated(workHash, participant, percentage); 29 | } 30 | 31 | function revokePricing(bytes32 workHash, address workOwner) public onlyWorkOwner(workOwner) { 32 | delete pricings[workHash]; 33 | emit PricingRevoked(workHash); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /contracts/business_template/traceability/Traceability.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | import "./Goods.sol"; 4 | 5 | contract Traceability{ 6 | struct GoodsData{ 7 | Goods traceGoods; 8 | bool valid; 9 | } 10 | bytes32 _category; 11 | mapping(uint64=>GoodsData) private _goods; 12 | constructor(bytes32 goodsTp) public { 13 | _category = goodsTp; 14 | } 15 | 16 | event newGoodsEvent(uint64 goodsId); 17 | 18 | function createGoods(uint64 goodsId) public returns(Goods){ 19 | require(!_goods[goodsId].valid, "is really exists"); 20 | 21 | _goods[goodsId].valid = true; 22 | Goods traceGoods = new Goods(goodsId); 23 | emit newGoodsEvent(goodsId); 24 | _goods[goodsId].traceGoods = traceGoods; 25 | return traceGoods; 26 | } 27 | 28 | function changeGoodsStatus(uint64 goodsId, int16 goodsStatus, string memory remark) public{ 29 | require(_goods[goodsId].valid, "not exists"); 30 | _goods[goodsId].traceGoods.changeStatus(goodsStatus, remark); 31 | } 32 | 33 | function getStatus(uint64 goodsId)public view returns(int16){ 34 | require(_goods[goodsId].valid, "not exists"); 35 | return _goods[goodsId].traceGoods.getStatus(); 36 | } 37 | 38 | function getGoods(uint64 goodsId)public view returns(Goods){ 39 | require(_goods[goodsId].valid, "not exists"); 40 | return _goods[goodsId].traceGoods; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /contracts/business_template/reward_point/LibRoles.sol: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * */ 16 | 17 | pragma solidity ^0.4.25; 18 | 19 | library LibRoles { 20 | struct Role { 21 | mapping (address => bool) bearer; 22 | } 23 | 24 | function add(Role storage role, address account) internal { 25 | require(!has(role, account), "Roles: account already has role"); 26 | role.bearer[account] = true; 27 | } 28 | 29 | function remove(Role storage role, address account) internal { 30 | require(has(role, account), "Roles: account does not have role"); 31 | role.bearer[account] = false; 32 | } 33 | 34 | function has(Role storage role, address account) internal view returns (bool) { 35 | require(account != address(0), "Roles: account is the zero address"); 36 | return role.bearer[account]; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /contracts/business_template/Medicine/BasicToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.21; 2 | 3 | import "./ERC20Basic.sol"; 4 | import "./SafeMath.sol"; 5 | 6 | /** 7 | * @title Basic token 8 | * @dev Basic version of StandardToken, with no allowances. 9 | */ 10 | contract BasicToken is ERC20Basic { 11 | using SafeMath for uint256; 12 | 13 | mapping(address => uint256) balances; 14 | 15 | uint256 totalSupply_; 16 | 17 | /** 18 | * @dev total number of tokens in existence 19 | */ 20 | function totalSupply() public view returns (uint256) { 21 | return totalSupply_; 22 | } 23 | 24 | /** 25 | * @dev transfer token for a specified address 26 | * @param _to The address to transfer to. 27 | * @param _value The amount to be transferred. 28 | */ 29 | function transfer(address _to, uint256 _value) public returns (bool) { 30 | require(_to != address(0)); 31 | require(_value <= balances[msg.sender]); 32 | 33 | balances[msg.sender] = balances[msg.sender].sub(_value); 34 | balances[_to] = balances[_to].add(_value); 35 | emit Transfer(msg.sender, _to, _value); 36 | return true; 37 | } 38 | 39 | /** 40 | * @dev Gets the balance of the specified address. 41 | * @param _owner The address to query the the balance of. 42 | * @return An uint256 representing the amount owned by the passed address. 43 | */ 44 | function balanceOf(address _owner) public view returns (uint256) { 45 | return balances[_owner]; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /docs/business_template/Evidence.md: -------------------------------------------------------------------------------- 1 | ## 存证模板背景说明 2 | 3 | 电子存证是一种用于保存证据的手段,应用场景很多,例如在版权领域,作者可以将作品指纹保存到电子存证机构,当出现版权纠纷时,可通过取证解决纠纷。存证、取证的关键环节是电子存证服务机构,如何保证它的可信性,即存证机构本身不会对存证数据进行破坏?传统的中心化存证机构很难解决这个问题,需要由区块链技术来解决。在区块链技术中,电子账本由各个节点共同维护,其内容由共识算法决定,单一节点无法篡改已达成共识的账本数据。这一不可篡改的特性是去中心化电子存证方案的核心。该方案中,存证数据不再存储于单一机构,而是分布式地存储在所有区块链节点上。 4 | 5 | ## 场景说明 6 | 7 | 本模板支持基于多签的存证场景。该场景中,包含几个角色:存证方、审核方、存储方、取证方: 8 | 9 | - 存证方:提交存证申请。 10 | - 审核方:审核存证申请,申请通过后交由存储方保存。 11 | - 存储方:保存存证数据。在去中心化方案中,由区块链上的智能合约充当存储方。 12 | - 取证方:提取存证数据。 13 | 14 | ## 接口 15 | 16 | 提供了三个合约:Evidence合约,EvidenceRepository合约,RequestRepository合约,Authentication合约。其中Evidence合约是对外服务合约,其余合约是辅助合约,用于数据和逻辑分离。 17 | 18 | Evidence合约:对外服务的唯一接口。包含: 19 | - createSaveRequest(byte32 hash, bytes ext): 存证方提交存证请求。hash是存证数据摘要,ext可选地存放说明信息 20 | - getRequestData(bytes32 hash): 审核方查看存证请求,以便审核。包括ext等信息 21 | - voteSaveRequest(bytes32 hash):审核方批准存证请求。投票全部通过后, 22 | - getEvidence(bytes32 hash): 取证方查看存证数据,包括时间戳、持有人等信息 23 | 24 | ## 使用示例 25 | 26 | 假如现在要创建一个2-3投票的存证合约,然后上传存证、审核存证、查看存证,整个过程如下: 27 | 28 | 合约初始化: 29 | 30 | - 管理员部署EvidenceRepository合约 31 | - 管理员部署RequestRepository合约,构造时传入threshold参数为2、voters列表为3个投票者 32 | - 管理员部署Evidence合约 33 | - 管理员调用EvidenceRepository.allow和RequestRepository.allow,参数传入Evidence合约地址,这一步是指定仅有Evidence合约可以调用EvidenceRepository和RequestRepository 34 | 35 | 合约调用: 36 | 37 | - 存证方调用Evidence.createSaveRequest提交存证请求 38 | - 审核者调用Evidence.getRequestData查看存证请求;调用voteSaveRequest批准审核请求 39 | - 审核通过后,取证方调用Evidence.getEvidence查看存证数据 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /contracts/common_tools/timelock/SafeMath.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.6.10; 2 | 3 | library SafeMath { 4 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 5 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 6 | // benefit is lost if 'b' is also tested. 7 | // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 8 | if (a == 0) { 9 | return 0; 10 | } 11 | 12 | uint256 c = a * b; 13 | require(c / a == b, "SafeMath: multiplication overflow"); 14 | 15 | return c; 16 | } 17 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 18 | // Solidity only automatically asserts when dividing by 0 19 | require(b > 0, "SafeMath: division by zero"); 20 | uint256 c = a / b; 21 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 22 | 23 | return c; 24 | } 25 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 26 | require(b <= a, "SafeMath: subtraction overflow"); 27 | uint256 c = a - b; 28 | 29 | return c; 30 | } 31 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 32 | uint256 c = a + b; 33 | require(c >= a, "SafeMath: addition overflow"); 34 | 35 | return c; 36 | } 37 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 38 | require(b != 0, "SafeMath: modulo by zero"); 39 | return a % b; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /contracts/data_structure/LibStack.sol: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * */ 16 | 17 | pragma solidity ^0.4.25; 18 | 19 | library LibStack{ 20 | 21 | 22 | struct Stack{ 23 | bytes32[] datas; 24 | } 25 | 26 | 27 | function push(Stack storage self, bytes32 data) internal{ 28 | self.datas.push(data); 29 | } 30 | 31 | function pop(Stack storage self) internal returns(bytes32){ 32 | require(self.datas.length > 0); 33 | bytes32 data = self.datas[self.datas.length - 1]; 34 | self.datas.length--; 35 | return data; 36 | } 37 | 38 | function peek(Stack storage self) internal returns(bytes32){ 39 | require(self.datas.length > 0); 40 | bytes32 data = self.datas[self.datas.length - 1]; 41 | return data; 42 | } 43 | function getSize(Stack storage self) internal view returns(uint256){ 44 | return self.datas.length; 45 | } 46 | } -------------------------------------------------------------------------------- /contracts/business_template/red_packet/proxy.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | 4 | //负责接受积分合约的授权,以完成积分转移 5 | contract Proxy { 6 | IPoint point; 7 | address owner; 8 | constructor() public { 9 | owner = msg.sender; 10 | } 11 | 12 | modifier onlyOwner() { 13 | require(msg.sender == owner, "only owner can do"); 14 | _; 15 | } 16 | 17 | function setPointAddr(address _addr) public onlyOwner { 18 | point = IPoint(_addr); 19 | } 20 | 21 | function transfer(address _from, address _to, uint256 _value) external returns (bool success) { 22 | point.transferFrom(_from, _to, _value); 23 | } 24 | 25 | function allowance(address _from) public view returns (uint256) { 26 | return point.allowance(_from, address(this)); 27 | } 28 | 29 | function balanceOf(address _who) public view returns (uint256) { 30 | return point.balanceOf(_who); 31 | } 32 | 33 | function addr() public view returns (address) { 34 | return address(this); 35 | } 36 | } 37 | 38 | interface IPoint { 39 | function balanceOf(address _owner) external view returns (uint256 balance); 40 | function transfer(address _to, uint256 _value) external returns (bool success); 41 | function approve(address _spender, uint256 _value) external returns (bool success); 42 | function transferFrom(address _from, address _to, uint256 _value) external returns (bool success); 43 | function allowance(address _owner, address _spender) external view returns (uint256 remaining); 44 | 45 | } -------------------------------------------------------------------------------- /contracts/business_template/CharityFund/SafeMath.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | 4 | library SafeMath { 5 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 6 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 7 | // benefit is lost if 'b' is also tested. 8 | // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 9 | if (a == 0) { 10 | return 0; 11 | } 12 | 13 | uint256 c = a * b; 14 | require(c / a == b, "SafeMath: multiplication overflow"); 15 | 16 | return c; 17 | } 18 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 19 | // Solidity only automatically asserts when dividing by 0 20 | require(b > 0, "SafeMath: division by zero"); 21 | uint256 c = a / b; 22 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 23 | 24 | return c; 25 | } 26 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 27 | require(b <= a, "SafeMath: subtraction overflow"); 28 | uint256 c = a - b; 29 | 30 | return c; 31 | } 32 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 33 | uint256 c = a + b; 34 | require(c >= a, "SafeMath: addition overflow"); 35 | 36 | return c; 37 | } 38 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 39 | require(b != 0, "SafeMath: modulo by zero"); 40 | return a % b; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /contracts/common_tools/privacy_computation/Fiat-Shamir-ZK/fiat_shamir_1.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import random 3 | import hashlib 4 | import libnum 5 | 6 | n=8269 7 | password="Hello" 8 | g= 11 9 | 10 | v = random.randint(1,n) 11 | c = random.randint(1,n) 12 | 13 | 14 | print("Password:\t\t",password) 15 | x = int(hashlib.md5(password.encode()).hexdigest()[:8], 16) % n 16 | print("Password hash(x):\t",x,"\t (last 8 bits)") 17 | 18 | 19 | y= pow(g,x,n) 20 | 21 | t = pow(g,v,n) 22 | 23 | r = (v - c * x) % (n-1) 24 | 25 | Result = ( pow(g,r,n) * pow(y,c,n)) % n 26 | 27 | print('\n======Phase 0: Agreed parameters============') 28 | print('P=',n,'\t(Prime number)') 29 | print('G=',g,'\t(Generator)') 30 | 31 | print('\n======Phase 1: Peggy sends y to Victor,Victor store y with Peggy ==================') 32 | print('y= g^x mod P=\t\t',y) 33 | 34 | print('\n======Phase 2: Peggy wants to login , She send t to Victor==================') 35 | print('v=',v,'\t(Peggy\'s random value)') 36 | print('t=g**v % n =\t\t',t) 37 | 38 | print('\n======Phase 3: Victor choose c randomly ,and sends it to Peggy==================') 39 | print('c=',c,'\t(Vitor\' random challenge)') 40 | 41 | print('\n======Phase 4: Peggy recieves c and calculate r=v-cx, sends r to Victor==================') 42 | print('r=v-cx =\t\t',r) 43 | 44 | print('\n======Phase 5: Victor calculates (g^r)*(y^c)== t? ==================') 45 | print('t= % n =\t\t',t) 46 | print('( (g**r) * (y**c) )=\t',Result) 47 | if (t==Result): 48 | print('\nPeggy has proven she knows password') 49 | else: 50 | print('\nPeggy has not proven she knows x') -------------------------------------------------------------------------------- /contracts/business_template/CarbonSystemManager/SafeMath.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | 4 | library SafeMath { 5 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 6 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 7 | // benefit is lost if 'b' is also tested. 8 | // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 9 | if (a == 0) { 10 | return 0; 11 | } 12 | 13 | uint256 c = a * b; 14 | require(c / a == b, "SafeMath: multiplication overflow"); 15 | 16 | return c; 17 | } 18 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 19 | // Solidity only automatically asserts when dividing by 0 20 | require(b > 0, "SafeMath: division by zero"); 21 | uint256 c = a / b; 22 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 23 | 24 | return c; 25 | } 26 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 27 | require(b <= a, "SafeMath: subtraction overflow"); 28 | uint256 c = a - b; 29 | 30 | return c; 31 | } 32 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 33 | uint256 c = a + b; 34 | require(c >= a, "SafeMath: addition overflow"); 35 | 36 | return c; 37 | } 38 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 39 | require(b != 0, "SafeMath: modulo by zero"); 40 | return a % b; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /contracts/business_template/carbon_frugal_evidence/SafeMath.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | 4 | library SafeMath { 5 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 6 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 7 | // benefit is lost if 'b' is also tested. 8 | // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 9 | if (a == 0) { 10 | return 0; 11 | } 12 | 13 | uint256 c = a * b; 14 | require(c / a == b, "SafeMath: multiplication overflow"); 15 | 16 | return c; 17 | } 18 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 19 | // Solidity only automatically asserts when dividing by 0 20 | require(b > 0, "SafeMath: division by zero"); 21 | uint256 c = a / b; 22 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 23 | 24 | return c; 25 | } 26 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 27 | require(b <= a, "SafeMath: subtraction overflow"); 28 | uint256 c = a - b; 29 | 30 | return c; 31 | } 32 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 33 | uint256 c = a + b; 34 | require(c >= a, "SafeMath: addition overflow"); 35 | 36 | return c; 37 | } 38 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 39 | require(b != 0, "SafeMath: modulo by zero"); 40 | return a % b; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /contracts/business_template/evidence/EvidenceRepository.sol: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * */ 16 | 17 | pragma solidity ^0.4.25; 18 | import "./Authentication.sol"; 19 | 20 | contract EvidenceRepository is Authentication { 21 | struct EvidenceData{ 22 | bytes32 hash; 23 | address owner; 24 | uint timestamp; 25 | } 26 | mapping(bytes32=>EvidenceData) private _evidences; 27 | 28 | function setData(bytes32 hash, address owner, uint timestamp) public auth { 29 | _evidences[hash].hash = hash; 30 | _evidences[hash].owner = owner; 31 | _evidences[hash].timestamp = timestamp; 32 | } 33 | 34 | function getData(bytes32 hash) public view returns(bytes32 , address, uint){ 35 | EvidenceData storage evidence = _evidences[hash]; 36 | require(evidence.hash == hash, "Evidence not exist"); 37 | return (evidence.hash, evidence.owner, evidence.timestamp); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /docs/business_template/MarriageEvidence.md: -------------------------------------------------------------------------------- 1 | ## 功能说明 2 | 3 | 本合约结合角色合约与存证合约打造结婚证书合约实例。也可根据需求开发毕业证书,参会,活动证明等,更多玩法可自由修改。 4 | 5 | ## 接口 6 | 7 | 提供了五个合约:Roles合约,Character合约,Evidence合约,EvidenceFactory合约,MarriageEvidence合约。其中Character合约是对外服务合约,Roles合约是库合约,用于数据和逻辑抽象化。其中Evidence合约是存证基合约,EvidenceFactory合约是存证工厂合约。 8 | 9 | **Character合约**:主要使用接口。包含: 10 | 11 | - addCharacter(address amount,string _summary): 管理员进行添加角色操作。amount是添加角色的地址,_ _summary添加角色的基本信息 12 | - getAllCharater():任何人都可以进行查看当前存在的所有角色操作。返回值:address[] 13 | 14 | **EvidenceFactory合约**:主要使用接口。包含: 15 | 16 | - constructor(address[] evidenceSigners) :构造函数。evidenceSigners是签名者地址数组,传入地址数组进行初始化授权 17 | - verify(address addr):验证addr地址是否为授权签名地址。返回值:bool 18 | - newEvidence(string evi):创建新证书功能。evi是存证信息。返回值:address (证书地址) 19 | - addSignatures(address addr) :进行签名。addr地址者签名。返回值:bool 20 | - getEvidence(address addr) :获取证书信息。addr是证书地址。返回值:存证信息string,授权地址address[],已签名地址address[] 21 | 22 | **MarriageEvidence**:继承Character合约,部署使用EvidenceFactory合约,主要对外接口。包含: 23 | 24 | - deployEvi():部署EvidenceFactory合约,导入夫妻地址 25 | - newEvi(string _evi):发布结婚存证 26 | - sign():夫妻签字 27 | - getEvi():查看证书 28 | 29 | 30 | 31 | ## 使用示例 32 | 33 | 角色的增删改查,整个过程如下: 34 | 35 | 合约初始化: 36 | 37 | - 以民政局管理员地址部署MarriageEvidence合约(继承于Character合约) 38 | 39 | 合约调用: 40 | 41 | - 管理员调用Character.addCharacter提交添加角色请求,参数传入添加夫妻的地址,夫妻的基本信息(json格式传入) 42 | - 管理员调用MarriageEvidence.deployEvi()提交部署EvidenceFactory合约请求,参数自动以Character.getAllCharater的返回值参入,为夫妻地址在证书中签名授权。 43 | - 管理员调用MarriageEvidence.newEvi提交创建结婚证书请求 44 | - 夫妻各自调用MarriageEvidence.sign提交对结婚证书进行签名请求 45 | - 任何人调用MarriageEvidence.getEvi提交查看结婚证书 -------------------------------------------------------------------------------- /docs/common_tools/FiatShamirZK.md: -------------------------------------------------------------------------------- 1 | # Fiat-Shamir 零知识证明协议 2 | 3 | ## 场景介绍 4 | 一般用户在网站注册账号的时候,网站会要求用户设置一个密码,然后在后台保存这个密码,用户登录网站的时候要求再输入这个密码,与后台保存的密码进行比较,确定是否给用户登录权限,但这种时候用户的密码容易受到字典攻击,有一些安全意识的网站会加盐保存密码的hash,增加敌手穷举用户密码或撞库的难度。但用户密码保存在网站后台服务器上始终增加了泄露的风险,Fiat-Shamir零知识证明协议可以允许用户向注册的网站证明自己知道自己的密码,而不向网站泄露任何关于密码的信息。 5 | 6 | ## Fiat-Shamir with secret password 7 | 首先Peggy(证明者,Prover)与Victor(验证者,Verifier)就公开参数(一个素数n,一个模n群的生成元g)达成共识。 8 | 1. Peggy首先选择她的密码,然后对密码进行哈希,把结果转成整型数值x。 9 | ``` 10 | x=int(Hash(passowrd)) 11 | y=g^x mod n 12 | ``` 13 | Peggy 把y的值发给 Victor,让他保存 14 | 15 | 2. 现在Peggy想要登录,她选择一个随机数v,计算 16 | ``` 17 | t = g^v mod n 18 | ``` 19 | 然后把t的值发给Victor 20 | 21 | 3. Victor收到t,然后发送随机数c给Peggy 22 | 23 | 4. Peggy生成随机数v,计算 24 | ``` 25 | r =v -cx mod (n-1) 26 | ``` 27 | Peggy把r发送给Victor 28 | 29 | 5. Victor计算 30 | ``` 31 | val=(g^r)(y^c) mod n 32 | ``` 33 | 然后判断val与t是否相等,若相等,则Peggy证明了自己知道密码,然后允许Peggy登录。 34 | 35 | ## 使用 36 | 1. 在链下使用contract_step1.py 计算 y值,然后在FiatShamir.sol中调用Step1_register 将y值登记。 37 | 2. 在链下使用contract_step2.py 计算 t值, 然后在FiatShamir.sol中调用Step2_login 传递t值。 38 | 3. 在FiatShamir.sol中调用Step3_randomchallenge 生成c值。 39 | 4. 查看c值并使用contract_step45.py 计算r值。 40 | 5. 在FiatShamir.sol中调用Step45_verify ,输入r值,输出true 或 false,表示验证通过与否。 41 | 42 | 其中各个函数的输入通过 链下运行 contract_step1.py 计算 y,contract_step2.py 计算t, contract_step45.py 计算r 。 43 | 44 | fiat_shamir_1.py 为整个交互过程的参考代码 45 | 46 | ## 参考文献 47 | [1] Fiat, Amos, and Adi Shamir. "How to prove yourself: Practical solutions to identification and signature problems." Conference on the Theory and Application of Cryptographic Techniques. Springer, Berlin, Heidelberg, 1986. -------------------------------------------------------------------------------- /contracts/common_tools/role/white_list/WhitelistAdminRole.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | import "./SafeRole.sol"; 4 | 5 | 6 | contract WhitelistAdminRole { 7 | using SafeRole for SafeRole.Role; 8 | 9 | event WhitelistAdminAdded(address indexed account); 10 | event WhitelistAdminRemoved(address indexed account); 11 | 12 | SafeRole.Role private _whitelistAdmins; 13 | 14 | /** 15 | * 构造器 16 | */ 17 | constructor () internal { 18 | _addWhitelistAdmin(msg.sender); 19 | } 20 | /** 21 | * 白名单管理员权限修饰符 22 | */ 23 | modifier onlyWhitelistAdmin() { 24 | require(isWhitelistAdmin(msg.sender), "WhitelistAdminRole: caller does not have the WhitelistAdmin role"); 25 | _; 26 | } 27 | /** 28 | * 判断是否是白名单管理员 29 | */ 30 | function isWhitelistAdmin(address account) public view returns (bool) { 31 | return _whitelistAdmins.has(account); 32 | } 33 | /** 34 | * 添加白名单管理员 35 | */ 36 | function addWhitelistAdmin(address account) public onlyWhitelistAdmin { 37 | _addWhitelistAdmin(account); 38 | } 39 | /** 40 | * 移除白名单管理员 41 | */ 42 | function renounceWhitelistAdmin() public { 43 | _removeWhitelistAdmin(msg.sender); 44 | } 45 | 46 | function _addWhitelistAdmin(address account) internal { 47 | _whitelistAdmins.add(account); 48 | emit WhitelistAdminAdded(account); 49 | } 50 | 51 | function _removeWhitelistAdmin(address account) internal { 52 | _whitelistAdmins.remove(account); 53 | emit WhitelistAdminRemoved(account); 54 | } 55 | } -------------------------------------------------------------------------------- /contracts/default/crypto/LibVerifySignature.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.6.10; 2 | /** 3 | * @author cuiyu 4 | * @title 数字签名验签 5 | **/ 6 | library LibVerifySignature { 7 | // 参数0 验签者地址 参数1 签名者地址 参数3 消息哈希值 参数4 数字签名 8 | function verifySignature(address verifier, address publicKey, bytes32 hash, bytes memory signature) public pure returns (bool) 9 | { 10 | //签名者与验签者不可相同 11 | require(verifier != publicKey, "invalid verifier"); 12 | 13 | // 检查数字签名的长度是否为65字节(65 = 1 + 32 + 32) 14 | require(65 == signature.length, "invalid signature length!"); 15 | 16 | // 因为需要调用ecrecover预编译函数,而ecrecover需要的参数包括数字签名的三个片段(r, s, v) 17 | bytes32 r; // signature的前32个字节 椭圆曲线数字签名输出 18 | bytes32 s; // signature的第33字节到第64字节 椭圆曲线数字签名输出 19 | uint8 v; // signature的第65字节 恢复标识符,数值为27或28 20 | // 在椭圆曲线算法中,依靠r和s可计算出曲线上的多个点,因此会恢复出两个不同的公钥及其地址,因此需要基于v值进行选择 21 | 22 | string memory prefix = "\x19Ethereum Signed Message:\n32"; //前缀,可理解为ecrecover函数使用的格式要求 23 | 24 | // 内联汇编在处理字节运算时,具有较低的gas消耗 25 | assembly { 26 | r := mload(add(signature, 32)) 27 | s := mload(add(signature, 64)) 28 | // 在fisco bcos的EVM实现中,v在内部只是0x0或0x1,需要通过加27进行调整 29 | v := add(byte(0, mload(add(signature, 96))), 27) 30 | 31 | if eq(or(eq(v, 27), eq(v, 28)), 0) { stop() } 32 | } 33 | 34 | // ecrecover预编译函数可以计算出签名者地址,通过与publicKey进行比对,即可得到验签结果 35 | return (ecrecover(keccak256(abi.encodePacked(prefix, hash)), v, r, s) == publicKey); 36 | 37 | } 38 | 39 | } 40 | 41 | -------------------------------------------------------------------------------- /contracts/common_tools/proxy/MinimalProxyFactory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.6.10; 3 | pragma experimental ABIEncoderV2; 4 | 5 | import "./MinimalProxy.sol"; 6 | 7 | contract MinimalProxyFactory is MinimalProxy { 8 | // 代理合约 9 | struct Proxy { 10 | uint256 id; 11 | address clone; 12 | string description; 13 | } 14 | // 一份逻辑合约对应多个代理合约 15 | mapping (address => Proxy[]) logic; 16 | 17 | event cloneProxy(Proxy proxy); 18 | 19 | function createCloneProxy(address implementation, string memory _description) public returns(address) { 20 | address clone = createClone(implementation); 21 | // Read slot from memory. 22 | uint length = logic[implementation].length; 23 | uint _id = logic[implementation].length == 0 ? 1: ++length; 24 | Proxy memory proxy = Proxy({id: _id, clone: clone, description: _description}); 25 | logic[implementation].push(proxy); 26 | emit cloneProxy(proxy); 27 | return clone; 28 | } 29 | 30 | function getClone(address implementation, uint256 id) public view returns(Proxy memory) { 31 | Proxy memory proxy; 32 | for (uint i=0; i < logic[implementation].length; i++) { 33 | if (logic[implementation][i].id == id) proxy = logic[implementation][i]; 34 | } 35 | require(proxy.clone != address(0), "The clone contract cannot be found"); 36 | return proxy; 37 | } 38 | 39 | function getClones(address implementation) public view returns(Proxy[] memory) { 40 | return logic[implementation]; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /contracts/business_template/reward_point/Admin.sol: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * */ 16 | 17 | pragma solidity ^0.4.25; 18 | 19 | import "./BasicAuth.sol"; 20 | import "./RewardPointController.sol"; 21 | import "./RewardPointData.sol"; 22 | 23 | 24 | contract Admin is BasicAuth { 25 | address public _dataAddress; 26 | address public _controllerAddress; 27 | 28 | constructor() public { 29 | RewardPointData data = new RewardPointData("Point of V1"); 30 | _dataAddress = address(data); 31 | RewardPointController controller = new RewardPointController(_dataAddress); 32 | _controllerAddress = address(controller); 33 | data.upgradeVersion(_controllerAddress); 34 | data.addIssuer(msg.sender); 35 | data.addIssuer(_controllerAddress); 36 | } 37 | 38 | function upgradeVersion(address newVersion) public { 39 | RewardPointData data = RewardPointData(_dataAddress); 40 | data.upgradeVersion(newVersion); 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /contracts/business_template/intellectualProperty/sol/CopyrightManager.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | 4 | 5 | contract CopyrightManager { 6 | 7 | 8 | struct Work { 9 | address owner; 10 | string title; 11 | uint256 timestamp; 12 | string metadata; 13 | bool exists; 14 | } 15 | 16 | mapping(bytes32 => Work) public works; 17 | 18 | event WorkRegistered(bytes32 indexed workHash, address indexed owner, string title, uint256 timestamp); 19 | event WorkUpdated(bytes32 indexed workHash, string newTitle, string newMetadata); 20 | event WorkRevoked(bytes32 indexed workHash); 21 | 22 | modifier onlyOwner(bytes32 workHash) { 23 | require(works[workHash].owner == tx.origin, "只有作品拥有者可以进行操作"); 24 | _; 25 | } 26 | 27 | function registerWork(bytes32 workHash, string _title, string _metadata) public { 28 | require(!works[workHash].exists, "作品已存在"); 29 | works[workHash] = Work(tx.origin, _title, now, _metadata, true); 30 | emit WorkRegistered(workHash, tx.origin, _title, now); 31 | } 32 | 33 | function updateWork(bytes32 workHash, string newTitle, string newMetadata) public onlyOwner(workHash) { 34 | require(works[workHash].exists, "作品不存在"); 35 | works[workHash].title = newTitle; 36 | works[workHash].metadata = newMetadata; 37 | emit WorkUpdated(workHash, newTitle, newMetadata); 38 | } 39 | 40 | function revokeWork(bytes32 workHash) public onlyOwner(workHash) { 41 | require(works[workHash].exists, "作品不存在"); 42 | delete works[workHash]; 43 | emit WorkRevoked(workHash); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /docs/data_structure/Map.md: -------------------------------------------------------------------------------- 1 | # Map.sol 2 | 3 | Map提供了基于bytes32主键、自定义类型值的可迭代、可查询的映射. 4 | 5 | ## 使用方法 6 | 7 | 首先需要通过import引入Map合约,然后通过"."进行方法调用,如下为调用例子: 8 | 9 | ``` 10 | pragma solidity >=0.4.24 <0.6.11; 11 | 12 | import "./Map.sol"; 13 | 14 | contract MyData is DataItem{ 15 | string name; 16 | int16 age; 17 | constructor(string n, int16 a){ 18 | name = n; 19 | age = a; 20 | } 21 | } 22 | 23 | contract Test { 24 | 25 | Map _map; 26 | constructor(){ 27 | _map = new Map(); 28 | } 29 | 30 | event Log(uint256 size); 31 | event LogKey(bytes32 key); 32 | function f() public { 33 | string memory name = "张三"; 34 | _map.insert(bytes32("10001"), new MyData(name, 32)); 35 | emit Log(_map.getSize()); 36 | //遍历 37 | for(Pair item = _map.iterate_start(); _map.can_iterate(item);item = _map.iterate_next(item)){ 38 | emit LogKey(item.getKey()); 39 | MyData data = MyData(item.getValue()); 40 | } 41 | } 42 | } 43 | ``` 44 | 45 | 46 | ## API列表 47 | 48 | 编号 | API | API描述 49 | ---|---|--- 50 | 1 | *function insert(bytes32 key, DataItem value)public* | 新增键值对 51 | 2 | *function getValue(bytes32 key)public view returns(DataItem)* |根据key获取value 52 | 3 | *function getSize()public view returns(uint256)* |获得当前mapping的容量 53 | 4 | *function isEmpty() public view returns(bool)* |是否为空 54 | 5 | *function isExists(bytes32 key) public view returns(bool)* |判断键值是否存在 55 | 6 | *function iterate_start() public view returns(Pair)* | 枚举key的游标 56 | 7 | *function can_iterate(Pair iter) public view returns(bool)* | 游标是否可用 57 | 8 | *function iterate_next(Pair iter) public view returns(Pair)* | 下一个游标值 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /contracts/business_template/reward_point/IssuerRole.sol: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * */ 16 | 17 | pragma solidity ^0.4.25; 18 | 19 | import "./LibRoles.sol"; 20 | 21 | contract IssuerRole { 22 | using LibRoles for LibRoles.Role; 23 | 24 | event IssuerAdded(address indexed account); 25 | event IssuerRemoved(address indexed account); 26 | 27 | LibRoles.Role private _issuers; 28 | 29 | constructor () internal { 30 | _issuers.add(msg.sender); 31 | } 32 | 33 | modifier onlyIssuer() { 34 | require(isIssuer(msg.sender), "IssuerRole: caller does not have the Issuer role"); 35 | _; 36 | } 37 | 38 | function isIssuer(address account) public view returns (bool) { 39 | return _issuers.has(account); 40 | } 41 | 42 | function addIssuer(address account) public { 43 | _issuers.add(account); 44 | emit IssuerAdded(account); 45 | } 46 | 47 | function renounceIssuer(address account) public onlyIssuer { 48 | _issuers.remove(account); 49 | emit IssuerRemoved(account); 50 | } 51 | } -------------------------------------------------------------------------------- /contracts/base_type/BasicDemo.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | import "./LibAddress.sol"; 3 | import "./LibConverter.sol" ; 4 | import "./LibSafeMathForUint256Utils.sol"; 5 | contract BasicDemo { 6 | 7 | function safeMathDemo() public view { 8 | uint256 a =25; 9 | uint256 b =20; 10 | // a + b 11 | uint256 c = LibSafeMathForUint256Utils.add(a,b); 12 | // a - b 13 | uint256 d = LibSafeMathForUint256Utils.sub(a,b); 14 | // a * b 15 | uint256 e = LibSafeMathForUint256Utils.mul(a,b); 16 | // a/b 17 | uint256 f = LibSafeMathForUint256Utils.div(a,b); 18 | } 19 | 20 | function modPower() public view { 21 | uint256 a=25; 22 | uint256 b=20; 23 | // a % b 24 | uint256 c = LibSafeMathForUint256Utils.mod(a,b); 25 | // a ^ b 26 | uint256 d = LibSafeMathForUint256Utils.power(a,b); 27 | } 28 | 29 | function convertDemo() public view{ 30 | uint256 a = 25; 31 | bytes memory b = LibConverter.uintToBytes(a); 32 | } 33 | 34 | function convertDemo2() public view{ 35 | bytes memory a = "25"; 36 | int b = LibConverter.bytesToInt(a); 37 | } 38 | 39 | function addressDemo() public view{ 40 | address addr = 0xE0f5206BBD039e7b0592d8918820024e2a7437b9; 41 | bytes memory bs=LibAddress.addressToBytes(addr); 42 | bs = new bytes(20); 43 | addr = LibAddress.bytesToAddress(bs); 44 | addr = 0xE0f5206BBD039e7b0592d8918820024e2a7437b9; 45 | string memory addrStr = LibAddress.addressToString(addr); 46 | string memory str="0xE0f5206BBD039e7b0592d8918820024e2a7437b9"; 47 | addr = LibAddress.stringToAddress(str); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /contracts/common_tools/history_snapshot/HistorySnapshot.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.6.10; 2 | pragma experimental ABIEncoderV2; 3 | 4 | contract HistorySnapshot { 5 | // 用一个结构体记录块高和其他想要记录的值 6 | struct Snapshot { 7 | uint blockNumber; 8 | string name; 9 | } 10 | // 当前值 11 | string _name; 12 | 13 | // 存储快照的数组 14 | Snapshot[] public _snapshotList; 15 | 16 | // 初始化 17 | constructor(string memory name) public { 18 | set(name); 19 | } 20 | 21 | // 更改当前值,并把值与当前块高push到快照数组 22 | function set(string memory name) public { 23 | _name = name; 24 | _snapshotList.push(Snapshot({ blockNumber: block.number, name: name })); 25 | } 26 | 27 | // 获取当前值 28 | function get() public view returns(string memory) { 29 | return _name; 30 | } 31 | 32 | // 调试用的获取当前块高 33 | function getBlockNumber() public view returns(uint) { 34 | return block.number; 35 | } 36 | 37 | // 通过块高获取值,用二分法找到<= blockNumber的最新值并返回 38 | function getByBlockNumber(uint blockNumber) public view returns(string memory) { 39 | require(blockNumber >= _snapshotList[0].blockNumber, "不存在!"); 40 | 41 | uint l = 0; 42 | uint r = _snapshotList.length - 1; 43 | while (l <= r) { 44 | uint m = (l + r) / 2; 45 | Snapshot memory snapshot = _snapshotList[m]; 46 | if (snapshot.blockNumber < blockNumber) { 47 | l = m + 1; 48 | } else if (snapshot.blockNumber > blockNumber) { 49 | r = m - 1; 50 | } else { 51 | return snapshot.name; 52 | } 53 | } 54 | return _snapshotList[r].name; 55 | } 56 | } -------------------------------------------------------------------------------- /contracts/business_template/marriage_evidence/MarriageEvidence.sol: -------------------------------------------------------------------------------- 1 | pragma solidity^0.4.25; 2 | import "./EvidenceFactory.sol"; 3 | import "./Character.sol"; 4 | 5 | contract MarriageEvidence is Character{ 6 | address admin; 7 | address eviContractAddress; 8 | address eviAddress; 9 | constructor() public Character{ 10 | admin = msg.sender; 11 | } 12 | 13 | modifier adminOnly{ 14 | require(msg.sender == admin ,"require admin"); 15 | _; 16 | } 17 | 18 | modifier charactersMustBeAddedFirst{ 19 | require(getAllCharater().length != 0,"It is null"); 20 | _; 21 | } 22 | 23 | modifier signersOnly{ 24 | require(EvidenceFactory(eviContractAddress).verify(msg.sender),"you not is signer"); 25 | _; 26 | } 27 | function deployEvi() external adminOnly charactersMustBeAddedFirst{ 28 | addCharacter(msg.sender,"民政局"); 29 | EvidenceFactory evi = new EvidenceFactory(getAllCharater()); 30 | eviContractAddress = address(evi); 31 | } 32 | 33 | function getSigners() public constant returns(address[]){ 34 | return EvidenceFactory(eviContractAddress).getSigners(); 35 | } 36 | 37 | function newEvi(string _evi)public adminOnly returns(address){ 38 | eviAddress = EvidenceFactory(eviContractAddress).newEvidence(_evi); 39 | return eviAddress; 40 | } 41 | 42 | function sign() public signersOnly returns(bool) { 43 | return EvidenceFactory(eviContractAddress).addSignatures(eviAddress); 44 | } 45 | function getEvi() public constant returns(string,address[],address[]){ 46 | return EvidenceFactory(eviContractAddress).getEvidence(eviAddress); 47 | } 48 | } -------------------------------------------------------------------------------- /contracts/business_template/chattel/utils/Ownable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | contract Ownable { 4 | address private _owner; 5 | 6 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 7 | 8 | /** 9 | * The Ownable constructor sets the original `owner` of the contract to the sender 10 | * account. 11 | */ 12 | constructor () internal { 13 | _owner = msg.sender; 14 | emit OwnershipTransferred(address(0), _owner); 15 | } 16 | 17 | /** 18 | * the address of the owner. 19 | */ 20 | function owner() public view returns (address) { 21 | return _owner; 22 | } 23 | 24 | /** 25 | * Throws if called by any account other than the owner. 26 | */ 27 | modifier onlyOwner() { 28 | require(isOwner(), "Ownable: not authorized"); 29 | _; 30 | } 31 | 32 | /** 33 | * true if `msg.sender` is the owner of the contract. 34 | */ 35 | function isOwner() public view returns (bool) { 36 | return msg.sender == _owner; 37 | } 38 | 39 | /** 40 | * Allows the current owner to transfer control of the contract to a newOwner. 41 | * newOwner The address to transfer ownership to. 42 | */ 43 | function transferOwnership(address newOwner) public onlyOwner { 44 | _transferOwnership(newOwner); 45 | } 46 | 47 | /** 48 | * Transfers control of the contract to a newOwner. 49 | * newOwner The address to transfer ownership to. 50 | */ 51 | function _transferOwnership(address newOwner) internal { 52 | require(newOwner != address(0), "Ownable: newOwner not be zero"); 53 | emit OwnershipTransferred(_owner, newOwner); 54 | _owner = newOwner; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /docs/business_template/HealthRecord.md: -------------------------------------------------------------------------------- 1 | ## 医疗档案模板背景说明 2 | 3 | 在医疗信息跨机构之间流通与共享的过程中会有很多数据共享的需求。但目前在医疗行业普遍存在医疗数据收集不全、管理不规范、存在信息孤岛、泄露个体隐私、数据灰色交易等多种问题,这些问题造成组织之间协作的信任成本高昂,从而制约了整个医疗行业服务质量的发展。区块链技术在数据共享安全、协同治理以及数据真实可溯不可篡改方面的优势,为不同机构间数据共享提供了便利。 4 | 5 | ## 场景说明 6 | 7 | 本模板提供患者医疗健康数据链上存证和数据共享的场景。该场景中,包含几个角色:患者、医生、第三方机构医疗信息使用者: 8 | 9 | - 患者/医生/第三方机构注册上链:患者/医生/第三方机构册个人相关信息,在链上存储; 10 | - 患者授权给医生/第三方机构:患者将自己id信息共享授权给医生/第三方机构; 11 | - 医生增加患者病历文件;医生获得患者授权后,将诊断报告文件信息上链,包括文件名、文件类型、文件哈希以及文件密钥; 12 | - 患者病历文件密钥获取:患者/医生/第三方机构去链上获取病历文件密钥信息;用于应用层对诊断报告文件解密; 13 | - 患者病历信息查询:患者/医生/第三方机构去链上查询患者的病历文件信息; 14 | 15 | 16 | HealthRecord合约:对外服务的唯一接口。包含: 17 | - signupPatient(string memory _ssid, string memory _name, uint8 _age): 患者注册 18 | - signupDoctor(string memory _name): 医生注册 19 | - signupAgency(string memory _name):第三方数据共享机构注册 20 | - grantAccessToDoctor(address doctor_id) public checkPatient(msg.sender) checkDoctor(doctor_id): 患者给医生授权,将医生id加入患者所属医生列表以及患者id加入医生管理的患者列表 21 | - getPatientInfoForDoctor(address pat): 医生获取相应患者信息 22 | - getPatientInfo(): 患者本人查询个人病历信息 23 | - getFileSecret(bytes32 fileHashId, string memory role, address id, address pat):获取文件密钥,在获取密钥后,在应用层对诊断报告文件进行解密 24 | - getFileInfoDoctor(address doc, address pat, bytes32 fileHashId): 医生查询患者某一诊断病历文件信息 25 | - getFileInfoPatient(address pat, bytes32 fileHashId): 患者查询自己某一诊断病历文件信息 26 | - grantAccessToAgency(address agency_id):患者给机构授权,将机构id加入患者所属机构列表以及患者id加入机构管理的患者列表 27 | - getPatientInfoForAgency(address pat): 第三方机构获取机构下患者信息 28 | - getFileInfoAgency(address agy, address pat, bytes32 fileHashId): 第三方机构查询患者某一诊断病历文件信息 29 | 30 | 31 | ## 使用示例 32 | 33 | 假如现在要创建一个医疗档案合约,整个过程如下: 34 | 35 | 合约初始化: 36 | 37 | - 管理员部署HealthRecord合约和Auth合约 38 | 39 | 合约调用: 40 | 41 | - 调用注册合约方法先进行相关机构及人员注册; 42 | - 再进行其他合约方法调用; 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /docs/default/crypto/LibDecode.md: -------------------------------------------------------------------------------- 1 | # LibDecode.sol 2 | 3 | LibDecode 提供基于solidity的签名和验证签名等功能 4 | 5 | ## 使用方法 6 | ### 签名 7 | ```shell script 8 | // 初始化基本对象 9 | var Web3 = require('web3'); 10 | var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); 11 | 12 | var account = web3.eth.accounts[0]; 13 | var sha3Msg = web3.sha3("abc"); 14 | var signedData = web3.eth.sign(account, sha3Msg); 15 | 16 | console.log("account: " + account); 17 | console.log("sha3(message): " + sha3Msg); 18 | console.log("Signed data: " + signedData); 19 | ``` 20 | ```shell script 21 | $ node test.js 22 | account: 0x60320b8a71bc314404ef7d194ad8cac0bee1e331 23 | sha3(message): 0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 24 | Signed data: 0xf4128988cbe7df8315440adde412a8955f7f5ff9a5468a791433727f82717a6753bd71882079522207060b681fbd3f5623ee7ed66e33fc8e581f442acbcf6ab800 25 | 26 | ``` 27 | ### 验签 28 | ```shell script 29 | pragma solidity ^0.4.25; 30 | import "./LibDecode.sol"; 31 | contract Test { 32 | // bytes memory signedString =hex"f4128988cbe7df8315440adde412a8955f7f5ff9a5468a791433727f82717a6753bd71882079522207060b681fbd3f5623ee7ed66e33fc8e581f442acbcf6ab800"; 33 | // bytes memory signhash =hex"4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45"; 34 | function decode(bytes signhash, bytes signedString) public view returns (address result) { 35 | return LibDecode.decode(signhash, signedString); 36 | } 37 | } 38 | ``` 39 | 40 | ## API列表 41 | 42 | 编号 | API | API描述 43 | ---|---|--- 44 | 1 | *decode(bytes signhash, bytes signedString) returns (address)* | 解码签名地址 45 | 46 | ## API详情 47 | 48 | ### ***1. decode 函数*** 49 | 50 | 解码签名地址 51 | 52 | #### 参数 53 | 54 | - signhash: sha3(msg) 55 | 56 | - signedString: 签名后的数据 57 | #### 返回值 58 | - address 59 | -------------------------------------------------------------------------------- /contracts/data_structure/LibQueue.sol: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * */ 16 | 17 | pragma solidity ^0.4.25; 18 | 19 | library LibQueue{ 20 | 21 | 22 | struct Queue{ 23 | uint256 first; 24 | uint256 next; 25 | mapping(uint => bytes32) queue; 26 | 27 | } 28 | 29 | function enqueue(Queue storage queue, bytes32 data) internal { 30 | queue.queue[queue.next++] = data; 31 | } 32 | 33 | function dequeue(Queue storage queue) internal returns (bytes32) { 34 | uint256 first = queue.first; 35 | require(queue.next > first); // non-empty queue 36 | 37 | bytes32 data = queue.queue[first]; 38 | delete queue.queue[first]; 39 | queue.first += 1; 40 | return data; 41 | } 42 | 43 | function element(Queue storage queue) internal view returns (bytes32) { 44 | uint256 first = queue.first; 45 | require(queue.next > first); // non-empty queue 46 | bytes32 data = queue.queue[first]; 47 | return data; 48 | } 49 | 50 | 51 | function getSize(Queue storage self) internal view returns(uint256){ 52 | return self.next - self.first; 53 | } 54 | } -------------------------------------------------------------------------------- /contracts/default/embeded_table/KVTableTest.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | import "./Table.sol"; 4 | 5 | contract KVTableTest { 6 | event SetResult(int256 count); 7 | 8 | KVTableFactory tableFactory; 9 | string constant TABLE_NAME = "t_kvtest"; 10 | 11 | constructor() public { 12 | //The fixed address is 0x1010 for KVTableFactory 13 | tableFactory = KVTableFactory(0x1010); 14 | // the parameters of createTable are tableName,keyField,"vlaueFiled1,vlaueFiled2,vlaueFiled3,..." 15 | tableFactory.createTable(TABLE_NAME, "id", "item_price,item_name"); 16 | } 17 | 18 | //get record 19 | function get(string memory id) public view returns (bool, int256, string memory) { 20 | KVTable table = tableFactory.openTable(TABLE_NAME); 21 | bool ok = false; 22 | Entry entry; 23 | (ok, entry) = table.get(id); 24 | int256 item_price; 25 | string memory item_name; 26 | if (ok) { 27 | item_price = entry.getInt("item_price"); 28 | item_name = entry.getString("item_name"); 29 | } 30 | return (ok, item_price, item_name); 31 | } 32 | 33 | //set record 34 | function set(string memory id, int256 item_price, string memory item_name) 35 | public 36 | returns (int256) 37 | { 38 | KVTable table = tableFactory.openTable(TABLE_NAME); 39 | Entry entry = table.newEntry(); 40 | // the length of entry's field value should < 16MB 41 | entry.set("id", id); 42 | entry.set("item_price", item_price); 43 | entry.set("item_name", item_name); 44 | // the first parameter length of set should <= 255B 45 | int256 count = table.set(id, entry); 46 | emit SetResult(count); 47 | return count; 48 | } 49 | } -------------------------------------------------------------------------------- /contracts/business_template/book_of_shares/interfaces/IMembersRepository.sol: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 LI LI of JINGTIAN & GONGCHENG. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * */ 16 | 17 | pragma solidity ^0.4.25; 18 | 19 | contract IMembersRepository { 20 | event AddMember(address indexed acct, uint256 qtyOfMembers); 21 | event RemoveMember(address indexed acct, uint256 qtyOfMembers); 22 | 23 | event AddShareToMember(uint256 indexed shareNumber, address indexed acct); 24 | event RemoveShareFromMember( 25 | uint256 indexed shareNumber, 26 | address indexed acct 27 | ); 28 | 29 | event PayInCapitalToMember(address indexed acct, uint256 amount); 30 | event SubAmountFromMember( 31 | address indexed acct, 32 | uint256 parValue, 33 | uint256 paidInAmount 34 | ); 35 | 36 | function isMember(address acct) external view returns (bool); 37 | 38 | function getMember(address acct) 39 | external 40 | view 41 | returns ( 42 | uint256[], 43 | uint256, 44 | uint256 45 | ); 46 | 47 | function getMemberAcctList() external view returns (address[]); 48 | 49 | function getQtyOfMembers() external view returns (uint256); 50 | } 51 | -------------------------------------------------------------------------------- /contracts/business_template/bill/utils/Ownable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | contract Ownable { 4 | address private _owner; 5 | 6 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 7 | 8 | /** 9 | * @dev The Ownable constructor sets the original `owner` of the contract to the sender 10 | * account. 11 | */ 12 | constructor () internal { 13 | _owner = msg.sender; 14 | emit OwnershipTransferred(address(0), _owner); 15 | } 16 | 17 | /** 18 | * @return the address of the owner. 19 | */ 20 | function owner() public view returns (address) { 21 | return _owner; 22 | } 23 | 24 | /** 25 | * @dev Throws if called by any account other than the owner. 26 | */ 27 | modifier onlyOwner() { 28 | require(isOwner(), "Ownable: not authorized"); 29 | _; 30 | } 31 | 32 | /** 33 | * @return true if `msg.sender` is the owner of the contract. 34 | */ 35 | function isOwner() public view returns (bool) { 36 | return msg.sender == _owner; 37 | } 38 | 39 | /** 40 | * @dev Allows the current owner to transfer control of the contract to a newOwner. 41 | * @param newOwner The address to transfer ownership to. 42 | */ 43 | function transferOwnership(address newOwner) public onlyOwner { 44 | _transferOwnership(newOwner); 45 | } 46 | 47 | /** 48 | * @dev Transfers control of the contract to a newOwner. 49 | * @param newOwner The address to transfer ownership to. 50 | */ 51 | function _transferOwnership(address newOwner) internal { 52 | require(newOwner != address(0), "Ownable: newOwner not be zero"); 53 | emit OwnershipTransferred(_owner, newOwner); 54 | _owner = newOwner; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /contracts/default/crypto/VerifySignature.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.6.10; 2 | /** 3 | * @author cuiyu 4 | * @title 数字签名验签 5 | **/ 6 | contract VerifySignature { 7 | // 参数0 验签者地址 参数1 签名者地址 参数3 消息哈希值 参数4 数字签名 8 | function verifySignature(address verifier, address publicKey, bytes32 hash, bytes memory signature) public pure returns (bool) 9 | { 10 | //签名者与验签者不可相同 11 | require(verifier != publicKey, "invalid verifier"); 12 | 13 | // 检查数字签名的长度是否为65字节(65 = 1 + 32 + 32) 14 | require(65 == signature.length, "invalid signature length!"); 15 | 16 | // 因为需要调用ecrecover预编译函数,而ecrecover需要的参数包括数字签名的三个片段(r, s, v) 17 | bytes32 r; // signature的前32个字节 椭圆曲线数字签名输出 18 | bytes32 s; // signature的第33字节到第64字节 椭圆曲线数字签名输出 19 | uint8 v; // signature的第65字节 恢复标识符,数值为27或28 20 | // 在椭圆曲线算法中,依靠r和s可计算出曲线上的多个点,因此会恢复出两个不同的公钥及其地址,因此需要基于v值进行选择 21 | 22 | string memory prefix = "\x19Ethereum Signed Message:\n32"; //前缀,可理解为ecrecover函数使用的格式要求 23 | 24 | // 内联汇编在处理字节运算时,具有较低的gas消耗 25 | assembly { 26 | r := mload(add(signature, 32)) 27 | s := mload(add(signature, 64)) 28 | // 在fisco bcos的EVM实现中,v在内部只是0x0或0x1,需要通过加27进行调整 29 | v := add(byte(0, mload(add(signature, 96))), 27) 30 | 31 | if eq(or(eq(v, 27), eq(v, 28)), 0) { stop() } 32 | } 33 | 34 | // ecrecover预编译函数可以计算出签名者地址,通过与publicKey进行比对,即可得到验签结果 35 | return (ecrecover(keccak256(abi.encodePacked(prefix, hash)), v, r, s) == publicKey); 36 | 37 | } 38 | 39 | function testVerifySignature(address signerToVerify, bytes32 hash, bytes memory signature) public view returns (bool result) { 40 | return verifySignature(msg.sender, signerToVerify, hash, signature); 41 | } 42 | 43 | } 44 | 45 | -------------------------------------------------------------------------------- /docs/default/crypto/LibCryptoHash.md: -------------------------------------------------------------------------------- 1 | # LibCryptoHash.sol 2 | 3 | LibCryptoHash 提供了solidity内置函数keccak256、sha3、ripemd160等计算摘要。 4 | 5 | ## 使用方法 6 | ```shell script 7 | pragma solidity ^0.4.25; 8 | import "./LibCryptoHash.sol"; 9 | 10 | contract test { 11 | function t_keccak(string memory s1) public view returns (bytes32 result) { 12 | return LibCryptoHash.getKeccak256(s1); 13 | } 14 | function t_sha3(string memory s1) public view returns (bytes32 result) { 15 | return LibCryptoHash.getSha3(s1); 16 | } 17 | function t_sha256(string memory s1) public view returns (bytes32 result) { 18 | return LibCryptoHash.getSha256(s1); 19 | } 20 | function t_ripemd160(string memory s1) public view returns (bytes20 result) { 21 | return LibCryptoHash.getRipemd160(s1); 22 | } 23 | } 24 | ``` 25 | 26 | ## API列表 27 | 28 | 编号 | API | API描述 29 | ---|---|--- 30 | 1 | *getKeccak256(string memory s1) public returns(bytes32 result)* | keccak256算法 31 | 2 | *getSha3(string memory s1) public returns(bytes32 result)* | sha3算法等同于keccak256。 32 | 3 | *getSha256(string memory s1) public returns(bytes32 result)* | sha256算法。 33 | 4 | *getRipemd160(string memory s1) public returns(bytes20 result)* | ripemd160算法。 34 | 35 | ## API详情 36 | 37 | ### ***1. getKeccak256 函数*** 38 | 39 | keccak256算法 40 | 41 | #### 参数 42 | 43 | - s1: 字符串 44 | 45 | #### 返回值 46 | - result: byte32 47 | 48 | ## API详情 49 | 50 | ### ***1. getSha3 函数*** 51 | 52 | sha3算法等同于keccak256 53 | 54 | #### 参数 55 | 56 | - s1: 字符串 57 | 58 | #### 返回值 59 | - result: byte32 60 | ## API详情 61 | 62 | ### ***1. getSha256 函数*** 63 | 64 | sha256算法 65 | 66 | #### 参数 67 | 68 | - s1: 字符串 69 | 70 | #### 返回值 71 | - result: byte32 72 | ## API详情 73 | 74 | ### ***1. getRipemd160 函数*** 75 | 76 | ripemd160算法 77 | 78 | #### 参数 79 | 80 | - s1: 字符串 81 | 82 | #### 返回值 83 | - result: byte20 -------------------------------------------------------------------------------- /contracts/business_template/gov_office/lib/Table.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | contract TableFactory { 3 | function openTable(string) public constant returns (Table); //open table 4 | function createTable(string,string,string) public constant returns(int); //create table 5 | } 6 | 7 | //select condition 8 | contract Condition { 9 | function EQ(string, int); 10 | function EQ(string, string); 11 | 12 | function NE(string, int); 13 | function NE(string, string); 14 | 15 | function GT(string, int); 16 | function GE(string, int); 17 | 18 | function LT(string, int); 19 | function LE(string, int); 20 | 21 | function limit(int); 22 | function limit(int, int); 23 | } 24 | 25 | //one record 26 | contract Entry { 27 | function getInt(string) public constant returns(int); 28 | function getAddress(string) public constant returns(address); 29 | function getBytes64(string) public constant returns(byte[64]); 30 | function getBytes32(string) public constant returns(bytes32); 31 | function getString(string) public constant returns(string); 32 | 33 | function set(string, int) public; 34 | function set(string, string) public; 35 | } 36 | 37 | //record sets 38 | contract Entries { 39 | function get(int) public constant returns(Entry); 40 | function size() public constant returns(int); 41 | } 42 | 43 | //Table main contract 44 | contract Table { 45 | //select api 46 | function select(string, Condition) public constant returns(Entries); 47 | //insert api 48 | function insert(string, Entry) public returns(int); 49 | //update api 50 | function update(string, Entry, Condition) public returns(int); 51 | //remove api 52 | function remove(string, Condition) public returns(int); 53 | 54 | function newEntry() public constant returns(Entry); 55 | function newCondition() public constant returns(Condition); 56 | } -------------------------------------------------------------------------------- /contracts/business_template/book_of_shares/lib/LibArrayForAddressUtils.sol: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * */ 16 | 17 | pragma solidity ^0.4.25; 18 | 19 | library LibArrayForAddressUtils { 20 | function firstIndexOf(address[] storage array, address key) 21 | internal 22 | view 23 | returns (bool, address) 24 | { 25 | if (array.length == 0) { 26 | return (false, 0); 27 | } 28 | 29 | for (uint256 i = 0; i < array.length; i++) { 30 | if (array[i] == key) { 31 | return (true, i); 32 | } 33 | } 34 | return (false, 0); 35 | } 36 | 37 | function removeByIndex(address[] storage array, uint256 index) internal { 38 | require(index < array.length, "ArrayForAddress: index out of bounds"); 39 | 40 | while (index < array.length - 1) { 41 | array[index] = array[index + 1]; 42 | index++; 43 | } 44 | array.length--; 45 | } 46 | 47 | function removeByValue(address[] storage array, address value) internal { 48 | uint256 index; 49 | bool isIn; 50 | (isIn, index) = firstIndexOf(array, value); 51 | if (isIn) { 52 | removeByIndex(array, index); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /contracts/business_template/red_packet/SafeMath.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | /** 4 | * @title SafeMath 5 | * @dev Math operations with safety checks that revert on error 6 | */ 7 | library SafeMath { 8 | 9 | /** 10 | * @dev Multiplies two numbers, reverts on overflow. 11 | */ 12 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 13 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 14 | // benefit is lost if 'b' is also tested. 15 | // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 16 | if (a == 0) { 17 | return 0; 18 | } 19 | 20 | uint256 c = a * b; 21 | require(c / a == b); 22 | 23 | return c; 24 | } 25 | 26 | /** 27 | * @dev Integer division of two numbers truncating the quotient, reverts on division by zero. 28 | */ 29 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 30 | require(b > 0); // Solidity only automatically asserts when dividing by 0 31 | uint256 c = a / b; 32 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 33 | 34 | return c; 35 | } 36 | 37 | /** 38 | * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend). 39 | */ 40 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 41 | require(b <= a); 42 | uint256 c = a - b; 43 | 44 | return c; 45 | } 46 | 47 | /** 48 | * @dev Adds two numbers, reverts on overflow. 49 | */ 50 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 51 | uint256 c = a + b; 52 | require(c >= a); 53 | 54 | return c; 55 | } 56 | 57 | /** 58 | * @dev Divides two numbers and returns the remainder (unsigned integer modulo), 59 | * reverts when dividing by zero. 60 | */ 61 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 62 | require(b != 0); 63 | return a % b; 64 | } 65 | } -------------------------------------------------------------------------------- /contracts/common_tools/counter.sol: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-License-Identifier: Apache-2.0 3 | */ 4 | pragma solidity >0.5.11; 5 | contract counter { 6 | //计数器mapper,以bytes32作为计数器key,uint256为当前计数器的技术值 7 | mapping(bytes32=>uint256) CounterOf; 8 | //counter 计数器id,operator 操作人地址,time 操作时间,preVal 操作前的值,finalVal 操作后的值 9 | event counterAddLog(bytes32 indexed counter,address indexed operator,uint time,uint preVal,uint finalVal); 10 | //计数器+1操作,需要传递计数器id,执行成功后,会提示计数前与计数后的值 11 | function counterAdd(bytes32 _countid)public returns(uint256 , uint256 ){ 12 | //获取当前计数器计数值,用户结果返回,方便用户对结果进行核验 13 | uint256 preVal = CounterOf[_countid]; 14 | //计数器val加1 15 | CounterOf[_countid] += 1; 16 | emit counterAddLog(_countid,msg.sender,block.timestamp,preVal,CounterOf[_countid]); 17 | return (preVal,CounterOf[_countid]); 18 | } 19 | //计数器-1操作,需要传递计数器id,执行成功后,会提示计数前与计数后的值 20 | function counterSub(bytes32 _countid)public returns(uint256 , uint256 ){ 21 | //获取当前计数器计数值,用户结果返回,方便用户对结果进行核验 22 | uint256 preVal = CounterOf[_countid]; 23 | if(preVal>0){ 24 | //计数器val减1 25 | CounterOf[_countid] -= 1; 26 | }else{ 27 | CounterOf[_countid]=0; 28 | } 29 | 30 | emit counterAddLog(_countid,msg.sender,block.timestamp,preVal,CounterOf[_countid]); 31 | return (preVal,CounterOf[_countid]); 32 | } 33 | //根据计数器id返回计数器当前的计数值 34 | function getCounter(bytes32 _countid)public view returns(uint256){ 35 | return CounterOf[_countid]; 36 | } 37 | //计数器归零 38 | function counterClear(bytes32 _countid)public returns(uint256 , uint256 ){ 39 | //获取当前计数器计数值,用户结果返回,方便用户对结果进行核验 40 | uint256 preVal = CounterOf[_countid]; 41 | CounterOf[_countid] = 0; 42 | emit counterAddLog(_countid,msg.sender,block.timestamp,preVal,CounterOf[_countid]); 43 | return (preVal,CounterOf[_countid]); 44 | } 45 | } -------------------------------------------------------------------------------- /contracts/data_structure/table/DataTable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | import "./Map.sol"; 4 | 5 | //数据行,定义为list的数据节点 6 | contract DataRow is DataItem, Map{ 7 | 8 | } 9 | 10 | //二维数据表 11 | contract DataTable{ 12 | Map _map; 13 | 14 | constructor(){ 15 | _map = new Map(); 16 | } 17 | 18 | function insertItem(bytes32 rowId, bytes32 colId, DataItem item) public { 19 | if(!_map.isExists(rowId)){ 20 | _map.insert(rowId, new DataRow()); 21 | } 22 | DataRow row = DataRow(_map.getValue(rowId)); 23 | row.insert(colId, item); 24 | } 25 | function getItem(bytes32 rowId, bytes32 colId) public view returns(DataItem){ 26 | require(_map.isExists(rowId), "the item is not exists"); 27 | DataRow row = DataRow(_map.getValue(rowId)); 28 | return row.getValue(colId); 29 | } 30 | 31 | function getRow(bytes32 rowId) public view returns(DataRow){ 32 | require(_map.isExists(rowId), "the row is not exists"); 33 | DataRow row = DataRow(_map.getValue(rowId)); 34 | return row; 35 | } 36 | 37 | function isExists(bytes32 rowId, bytes32 colId) public view returns(bool){ 38 | if(!_map.isExists(rowId)){ 39 | return false; 40 | } 41 | DataRow row = DataRow(_map.getValue(rowId)); 42 | return row.isExists(colId); 43 | } 44 | 45 | function isExists(bytes32 rowId) public view returns(bool){ 46 | return _map.isExists(rowId); 47 | } 48 | 49 | function rowCount()public view returns(uint256){ 50 | return _map.getSize(); 51 | } 52 | 53 | function iterate_start() public view returns(Pair){ 54 | return _map.iterate_start(); 55 | } 56 | 57 | function iterate_next(Pair iter) public view returns(Pair){ 58 | return _map.iterate_next(iter); 59 | } 60 | 61 | function can_iterate(Pair iter) public view returns(bool){ 62 | return _map.can_iterate (iter); 63 | } 64 | } -------------------------------------------------------------------------------- /docs/common_tools/RBAC.md: -------------------------------------------------------------------------------- 1 | # 权限管理 2 | 权限管理有四个合约 3 | 1. Roles library 用于角色管理 4 | 2. RBAC 合约 管理用户和角色的映射关系 5 | 3. Ownable 合约 对合约的所属权进行管理 6 | 4. Example 合约 使用上述三个合约完成的一个小例子 7 | 8 | ## Roles 9 | 编号 | API | API描述 10 | ---|---|--- 11 | 1 | *function addRole(Role storage role ,address addr) internal* | 添加某个角色里的用户 12 | 2 | *function removeRole(Role storage role,address addr) internal* | 移除某个角色里的用户 13 | 3 | *function hasRole(Role storage role,address addr) internal view returns(bool)* | 检查某个角色下是否有某个用户 14 | 4 | *function checkRole(Role storage role,address addr) public view* | 确保某个用户属于某个角色,否则revert 15 | 16 | 17 | ## RBAC 18 | 编号 | API | API描述 19 | ---|---|--- 20 | 1 | *function addRole(address _operater, string memory _role) internal* | 添加某个角色里的用户 21 | 2 | *function removeRole(address _operater, string memory _role) internal* | 移除某个角色里的用户 22 | 3 | *function hasRole(address _operater, string memory _role) public view returns(bool)* | 检查某个角色下是否有某个用户 23 | 4 | *function checkRole(address _operater, string memory _role) public view* | 确保某个用户属于某个角色,否则revert 24 | 5 | *modifier onlyRole(string memory _role)*| 修饰符确保只有某个角色可以操作 25 | 26 | 27 | ## Ownable 28 | 编号 | API | API描述 29 | ---|---|--- 30 | 1 | *modifier onlyOwner* | 修饰符确保只有owner可以操作 31 | 2 | *function renounceOwnership() public onlyOwner* | 放弃owner权限 32 | 3 | *function transferOwnership(address _newOwner) public onlyOwner* | 将owner权限转给其他地址 33 | 34 | 35 | ## Example 36 | 在 Example 实现了加、减、乘、除四个方法,对应了四种权限,只有拥有相应的权限才可以进行相应的操作。 37 | 38 | 编号 | API | API描述 39 | ---|---|--- 40 | 1 | *function setRole(address addr,string memory _role) public onlyOwner* | 设置给某个地址设置某个角色 41 | 2 | *function resetRole(address addr,string memory _role) public onlyOwner* | 移除某个地址的某个角色 42 | 3 | *function add(uint a,uint b) public view onlyRole(ADD) returns(uint)* | 加 43 | 4 | *function sub(uint a,uint b) public view onlyRole(SUB) returns(uint)* | 减 44 | 5 | *function mul(uint a,uint b) public view onlyRole(MUL) returns(uint)* | 乘 45 | 6 | *function div(uint a,uint b) public view onlyRole(DIV) returns(uint)* | 除 46 | 47 | -------------------------------------------------------------------------------- /contracts/business_template/carbon_frugal_evidence/EvidencesRepository.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | library EvidencesRepository { 4 | struct Evidence { 5 | mapping (address=>mapping(bytes32=>EvidenceInfo)) bearer; 6 | } 7 | 8 | struct EvidenceInfo{ 9 | string dataJson;//原始摘要数据 10 | bytes signStr;//摘要数据Hash签名 11 | string timeCertificate;//授时凭证 12 | bool existState;// true 正常,flase 关闭 13 | uint createTimeStamp;//创建时间戳 14 | bool removeState;//移除 标识,存在为true 15 | uint removeTimeStamp;//删除时间戳 16 | } 17 | 18 | function add(Evidence storage evidence, address account,bytes32 dataHash, string dataJson,bytes signStr,string timeCertificate) internal { 19 | require(!has(evidence, account,dataHash), "EvidencesRepositorys add: 当前存证Hash已经存在!"); 20 | 21 | evidence.bearer[account][dataHash].dataJson = dataJson; 22 | evidence.bearer[account][dataHash].signStr = signStr; 23 | evidence.bearer[account][dataHash].timeCertificate = timeCertificate; 24 | evidence.bearer[account][dataHash].existState = true; 25 | evidence.bearer[account][dataHash].createTimeStamp = now; 26 | } 27 | 28 | function remove(Evidence storage evidence, address account,bytes32 dataHash) internal { 29 | require(has(evidence, account,dataHash), "EvidencesRepositorys remove: 不存在当前的注册用户!"); 30 | evidence.bearer[account][dataHash].removeState= true; 31 | evidence.bearer[account][dataHash].removeTimeStamp = now; 32 | } 33 | 34 | function has(Evidence storage evidence, address account,bytes32 dataHash) internal view returns (bool) { 35 | require(account != address(0), "EvidencesRepositorys has: 账户为空地址!"); 36 | return evidence.bearer[account][dataHash].existState; 37 | } 38 | 39 | //查找对应的用户存证 40 | function selectEvidence(Evidence storage evidence,address account,bytes32 dataHash) internal view returns(string){ 41 | return evidence.bearer[account][dataHash].dataJson; 42 | } 43 | } -------------------------------------------------------------------------------- /contracts/business_template/bill/utils/Table.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | contract TableFactory { 4 | function openTable(string) public constant returns (Table); // 打开表 5 | function createTable(string,string,string) public returns(int); // 创建表 6 | } 7 | 8 | // 查询条件 9 | contract Condition { 10 | //等于 11 | function EQ(string, int) public; 12 | function EQ(string, string) public; 13 | 14 | //不等于 15 | function NE(string, int) public; 16 | function NE(string, string) public; 17 | 18 | //大于 19 | function GT(string, int) public; 20 | //大于或等于 21 | function GE(string, int) public; 22 | 23 | //小于 24 | function LT(string, int) public; 25 | //小于或等于 26 | function LE(string, int) public; 27 | 28 | //限制返回记录条数 29 | function limit(int) public; 30 | function limit(int, int) public; 31 | } 32 | 33 | // 单条数据记录 34 | contract Entry { 35 | function getInt(string) public constant returns(int); 36 | function getAddress(string) public constant returns(address); 37 | function getBytes64(string) public constant returns(byte[64]); 38 | function getBytes32(string) public constant returns(bytes32); 39 | function getString(string) public constant returns(string); 40 | 41 | function set(string, int) public; 42 | function set(string, string) public; 43 | function set(string, address) public; 44 | } 45 | 46 | // 数据记录集 47 | contract Entries { 48 | function get(int) public constant returns(Entry); 49 | function size() public constant returns(int); 50 | } 51 | 52 | // Table主类 53 | contract Table { 54 | // 查询接口 55 | function select(string, Condition) public constant returns(Entries); 56 | // 插入接口 57 | function insert(string, Entry) public returns(int); 58 | // 更新接口 59 | function update(string, Entry, Condition) public returns(int); 60 | // 删除接口 61 | function remove(string, Condition) public returns(int); 62 | 63 | function newEntry() public constant returns(Entry); 64 | function newCondition() public constant returns(Condition); 65 | } -------------------------------------------------------------------------------- /contracts/business_template/chattel/utils/Table.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | contract TableFactory { 4 | function openTable(string) public constant returns (Table); // 打开表 5 | function createTable(string,string,string) public returns(int); // 创建表 6 | } 7 | 8 | // 查询条件 9 | contract Condition { 10 | //等于 11 | function EQ(string, int) public; 12 | function EQ(string, string) public; 13 | 14 | //不等于 15 | function NE(string, int) public; 16 | function NE(string, string) public; 17 | 18 | //大于 19 | function GT(string, int) public; 20 | //大于或等于 21 | function GE(string, int) public; 22 | 23 | //小于 24 | function LT(string, int) public; 25 | //小于或等于 26 | function LE(string, int) public; 27 | 28 | //限制返回记录条数 29 | function limit(int) public; 30 | function limit(int, int) public; 31 | } 32 | 33 | // 单条数据记录 34 | contract Entry { 35 | function getInt(string) public constant returns(int); 36 | function getAddress(string) public constant returns(address); 37 | function getBytes64(string) public constant returns(byte[64]); 38 | function getBytes32(string) public constant returns(bytes32); 39 | function getString(string) public constant returns(string); 40 | 41 | function set(string, int) public; 42 | function set(string, string) public; 43 | function set(string, address) public; 44 | } 45 | 46 | // 数据记录集 47 | contract Entries { 48 | function get(int) public constant returns(Entry); 49 | function size() public constant returns(int); 50 | } 51 | 52 | // Table主类 53 | contract Table { 54 | // 查询接口 55 | function select(string, Condition) public constant returns(Entries); 56 | // 插入接口 57 | function insert(string, Entry) public returns(int); 58 | // 更新接口 59 | function update(string, Entry, Condition) public returns(int); 60 | // 删除接口 61 | function remove(string, Condition) public returns(int); 62 | 63 | function newEntry() public constant returns(Entry); 64 | function newCondition() public constant returns(Condition); 65 | } -------------------------------------------------------------------------------- /contracts/common_tools/clone/BallotFactory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | /// @author Steve Jin 3 | 4 | pragma solidity >=0.8.0; 5 | pragma experimental ABIEncoderV2; 6 | 7 | // 导入了 CloneFactory 合约的代码。 8 | import {ICloneFactory} from "./CloneFactory.sol"; 9 | 10 | // 定义了 IBallot 接口,该接口包含一个 init 方法,用于初始化投票合约。 11 | interface IBallot { 12 | function init( 13 | bytes32 _subjectName, 14 | bytes32[] memory _proposalNames 15 | ) external; 16 | } 17 | 18 | contract BallotFactory { 19 | 20 | // immutable 关键字用于声明一个不可变的变量。声明了一个名为 CLONE_FACTORY 的不可变地址变量。 21 | address public immutable _CLONE_FACTORY_; 22 | 23 | // 声明了一个名为 _BALLOT_TEMPLATE_ 的投票原型合约的地址 24 | address public _BALLOT_TEMPLATE_; 25 | 26 | // 合约拥有者 27 | address public _OWNER_; 28 | 29 | // modifier 关键字用于定义一个函数修饰符。定义了 onlyOwner 修饰符,该修饰符要求只有合约拥有者才能执行修饰的函数。 30 | modifier onlyOwner() { 31 | require(msg.sender == _OWNER_, "NOT_OWNER"); 32 | _; 33 | } 34 | 35 | // 声明了一个构造函数,用于初始化 BallotFactory 合约的状态变量:克隆工厂合约的地址、投票原型合约的地址。 36 | constructor( 37 | address cloneFactory, 38 | address ballotTemplate 39 | ) { 40 | _CLONE_FACTORY_ = cloneFactory; 41 | _BALLOT_TEMPLATE_ = ballotTemplate; 42 | _OWNER_ = msg.sender; 43 | } 44 | 45 | // 定义了 createBallot 函数,用于创建一个新的投票合约,并返回新的投票合约的地址。 46 | // 该行代码使用 onlyOwner 修饰符,要求只有合约拥有者才能调用该函数。 47 | function createBallot( 48 | bytes32 _subjectName, 49 | bytes32[] memory _proposalNames 50 | ) external payable returns (address newBallot) { 51 | // 该行代码使用 ICloneFactory 接口,用于调用 CloneFactory 合约中的 clone 方法,创建新的投票合约。 52 | newBallot = ICloneFactory(_CLONE_FACTORY_).clone(_BALLOT_TEMPLATE_); 53 | // 该行代码使用 IBallot 接口,用于调用新创建的投票合约的 init 方法,初始化投票合约的信息 54 | IBallot(newBallot).init(_subjectName, _proposalNames); 55 | } 56 | 57 | // ============ 管理员操作更新原型合约地址 ============= 58 | function updateBallotTemplate(address newBallotTemplate) external onlyOwner { 59 | _BALLOT_TEMPLATE_ = newBallotTemplate; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /contracts/business_template/shared_bike/UserStorage.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.6.10; 2 | 3 | contract UserStorage{ 4 | 5 | address public admin; 6 | 7 | struct User { 8 | string name; 9 | string contact; 10 | uint32 creditPoints; 11 | uint32 status; 12 | } 13 | 14 | mapping(address=>User) private registeredUsers; 15 | 16 | constructor(address _admin) public{ 17 | admin = _admin; 18 | } 19 | 20 | modifier onlyAdmin(){ 21 | require(msg.sender == admin, "admin required"); 22 | _; 23 | } 24 | 25 | event RegisterUser(address indexed addr, string name, string contact); 26 | 27 | function registerUser(string memory name, string memory contact) external { 28 | require(!exists(msg.sender), "user existed"); 29 | User storage user = registeredUsers[msg.sender]; 30 | user.name = name; 31 | user.contact = contact; 32 | emit RegisterUser(msg.sender, name, contact); 33 | } 34 | 35 | function getCredits(address user) external view returns(uint32 credits) { 36 | require(exists(user), "user not exists"); 37 | return registeredUsers[user].creditPoints; 38 | } 39 | 40 | function exists(address user) public view returns(bool) { 41 | return registeredUsers[user].status != 0; 42 | } 43 | 44 | function addCredits(address user, uint32 credits) public onlyAdmin { 45 | require(credits > 0, "credits zero"); 46 | require(exists(user), "user not exists"); 47 | uint32 newPoint = registeredUsers[user].creditPoints + credits; 48 | require(newPoint > credits, "overflow"); 49 | registeredUsers[user].creditPoints= newPoint; 50 | } 51 | 52 | function subCredits(address user, uint32 credits) public onlyAdmin { 53 | require(credits > 0, "credits zero"); 54 | require(exists(user), "user not exists"); 55 | uint32 newPoint = registeredUsers[user].creditPoints - credits; 56 | require(newPoint < credits, "overflow"); 57 | registeredUsers[user].creditPoints= newPoint; 58 | } 59 | } -------------------------------------------------------------------------------- /contracts/common_tools/math/MathAdvance.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | /** 4 | * @author wpzczbyqy 5 | * @description 数学方法:开方、指数运算、对数运算,暂时保留到整数位且为截取而不是四舍五入 6 | **/ 7 | 8 | library MathAdvance { 9 | /** 10 | *开方 11 | *@param x, 对x进行开方 12 | *@return uint 返回整数位,小数位舍弃 13 | **/ 14 | function sqrt(uint x) public pure returns(uint) { 15 | uint z = (x + 1 ) / 2; 16 | uint y = x; 17 | while(z < y){ 18 | y = z; 19 | z = ( x / z + z ) / 2; 20 | } 21 | return y; 22 | } 23 | 24 | /** 25 | *以2为底的对数运算 26 | *@param x, 对x进行以2为底的对数运算 27 | *@return uint 返回整数位,小数位舍弃 28 | **/ 29 | function log2(uint x) public pure returns(uint) { 30 | for(int i = 0; ;i++) { 31 | if(exp2(i) <= x && exp2(i+1) > x){ 32 | return uint(i); 33 | } 34 | } 35 | return 0; 36 | } 37 | 38 | /** 39 | *以任意数为底的对数运算 40 | *@param m, 以m底 41 | *@param n, 对n进行以m为底的对数运算 42 | *@return uint 返回整数位,小数位舍弃 43 | **/ 44 | function log(uint m, uint n) public pure returns(uint) { 45 | for(int i = 0; ;i++) { 46 | if(uint(exp(int(m),i)) <= n && uint(exp(int(m), i+1)) > n){ 47 | return uint(i); 48 | } 49 | } 50 | return 0; 51 | } 52 | 53 | /** 54 | *2的N次幂运算 55 | *@param n, 对n进行以m为底的对数运算 56 | *@return uint 返回结果 57 | **/ 58 | function exp2(int n) public pure returns(uint) { 59 | if (n >= 0){ 60 | return uint((1 << n)); 61 | } 62 | return 0; 63 | } 64 | 65 | /** 66 | *m的n次幂运算 67 | *@param m, int类型 68 | *@param n, int类型 对m进行以n次幂运算 69 | *@return int 返回结果 70 | **/ 71 | function exp(int m, int n) public pure returns(int) { 72 | if(n < 0){ 73 | return 0; 74 | } 75 | 76 | if(m > 0){ 77 | return int(uint(m) ** uint(n)); 78 | } 79 | 80 | if(n % 2 == 0){ 81 | return int(uint(-m) ** uint(n)); 82 | } 83 | return int(-uint(-m) ** uint(n)); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /docs/data_structure/LibMaxHeapUint256.md: -------------------------------------------------------------------------------- 1 | # LibMaxHeapUint256.sol 2 | 3 | LibMaxHeapUint256提供了最大堆的实现。 4 | 5 | ## 使用方法 6 | 7 | 首先需要通过import引入类库,然后通过"."进行方法调用,如下为调用例子: 8 | 9 | ``` 10 | 11 | pragma solidity >=0.4.24 <0.6.11; 12 | 13 | import "./LibMaxHeapUint256.sol"; 14 | 15 | contract Test { 16 | 17 | using LibMaxHeapUint256 for LibMaxHeapUint256.Heap; 18 | 19 | LibMaxHeapUint256.Heap private _heap; 20 | 21 | function insertExample(uint256 value) public returns(uint256) { 22 | _heap.insert(value); 23 | } 24 | } 25 | ``` 26 | 27 | 28 | ## API列表 29 | 30 | 编号 | API | API描述 31 | ---|---|--- 32 | 1 | *insert(Heap storage heap, uint256 value) internal* | 向堆中插入一个元素 33 | 2 | *top(Heap storage heap) internal view returns (uint256)* |查询堆顶元素(最大值) 34 | 3 | *extractTop(Heap storage heap) internal returns(uint256 top)* |弹出堆顶元素(最大值) 35 | 4 | *getSize(Heap storage heap) internal view returns(uint256)* | 查询堆元素数 36 | 37 | ## API详情 38 | 39 | ### ***1. insert 函数*** 40 | 41 | 向堆中插入一个元素 42 | 43 | #### 参数 44 | 45 | - Heap heap:堆 46 | - uint256 value:元素 47 | 48 | #### 实例 49 | 50 | ``` 51 | function insertExample(uint256 value) public returns(uint256) { 52 | _heap.insert(value); 53 | } 54 | 55 | ``` 56 | ### ***2. top 函数*** 57 | 58 | 查询堆顶 59 | 60 | #### 参数 61 | 62 | - Heap heap:堆 63 | 64 | #### 返回值 65 | 66 | - uint256: 堆顶元素 67 | 68 | #### 实例 69 | 70 | ``` 71 | function topExample() public returns(uint256 top) { 72 | top = _heap.top(); 73 | } 74 | 75 | ``` 76 | ### ***3. extractTop 函数*** 77 | 78 | 弹出堆顶元素 79 | 80 | #### 参数 81 | 82 | - Heap heap:堆 83 | 84 | #### 返回值 85 | 86 | - uint256: 堆顶元素 87 | 88 | #### 实例 89 | 90 | ``` 91 | function extractTopExample() public returns(uint256 top) { 92 | top = _heap.extractTop(); 93 | } 94 | ``` 95 | 96 | ### ***4. getSize 函数*** 97 | 98 | 获取堆元素数 99 | 100 | #### 参数 101 | 102 | - Heap heap:堆 103 | 104 | #### 返回值 105 | 106 | - uint256: 堆元素数 107 | 108 | #### 实例 109 | 110 | ``` 111 | function getSize() public returns(uint256 size) { 112 | size = _heap.getSize(); 113 | } 114 | ``` -------------------------------------------------------------------------------- /docs/data_structure/LibMinHeapUint256.md: -------------------------------------------------------------------------------- 1 | # LibMinHeapUint256.sol 2 | 3 | LibMinHeapUint256提供了最小堆的实现。 4 | 5 | ## 使用方法 6 | 7 | 首先需要通过import引入类库,然后通过"."进行方法调用,如下为调用例子: 8 | 9 | ``` 10 | 11 | pragma solidity >=0.4.24 <0.6.11; 12 | 13 | import "./LibMinHeapUint256.sol"; 14 | 15 | contract Test { 16 | 17 | using LibMinHeapUint256 for LibMinHeapUint256.Heap; 18 | 19 | LibMinHeapUint256.Heap private _heap; 20 | 21 | function insertExample(uint256 value) public returns(uint256) { 22 | _heap.insert(value); 23 | } 24 | } 25 | ``` 26 | 27 | 28 | ## API列表 29 | 30 | 编号 | API | API描述 31 | ---|---|--- 32 | 1 | *insert(Heap storage heap, uint256 value) internal* | 向堆中插入一个元素 33 | 2 | *top(Heap storage heap) internal view returns (uint256)* |查询堆顶元素(最小值) 34 | 3 | *extractTop(Heap storage heap) internal returns(uint256 top)* |弹出堆顶元素(最小值) 35 | 4 | *getSize(Heap storage heap) internal view returns(uint256)* | 查询堆元素数 36 | 37 | ## API详情 38 | 39 | ### ***1. insert 函数*** 40 | 41 | 向堆中插入一个元素 42 | 43 | #### 参数 44 | 45 | - Heap heap:堆 46 | - uint256 value:元素 47 | 48 | #### 实例 49 | 50 | ``` 51 | function insertExample(uint256 value) public returns(uint256) { 52 | _heap.insert(value); 53 | } 54 | 55 | ``` 56 | ### ***2. top 函数*** 57 | 58 | 查询堆顶 59 | 60 | #### 参数 61 | 62 | - Heap heap:堆 63 | 64 | #### 返回值 65 | 66 | - uint256: 堆顶元素 67 | 68 | #### 实例 69 | 70 | ``` 71 | function topExample() public returns(uint256 top) { 72 | top = _heap.top(); 73 | } 74 | 75 | ``` 76 | ### ***3. extractTop 函数*** 77 | 78 | 弹出堆顶元素 79 | 80 | #### 参数 81 | 82 | - Heap heap:堆 83 | 84 | #### 返回值 85 | 86 | - uint256: 堆顶元素 87 | 88 | #### 实例 89 | 90 | ``` 91 | function extractTopExample() public returns(uint256 top) { 92 | top = _heap.extractTop(); 93 | } 94 | ``` 95 | 96 | ### ***4. getSize 函数*** 97 | 98 | 获取堆元素数 99 | 100 | #### 参数 101 | 102 | - Heap heap:堆 103 | 104 | #### 返回值 105 | 106 | - uint256: 堆元素数 107 | 108 | #### 实例 109 | 110 | ``` 111 | function getSize() public returns(uint256 size) { 112 | size = _heap.getSize(); 113 | } 114 | ``` -------------------------------------------------------------------------------- /contracts/business_template/marriage_evidence/EvidenceFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | import "Evidence.sol"; 3 | 4 | contract EvidenceFactory{ 5 | address[] signers; //存储签名者地址 6 | event newEvidenceEvent(address addr); //新签证事件,返回地址 7 | //传入签名内容 string类型,创建合约Evidence并初始化 8 | function newEvidence(string evi)public returns(address) 9 | { 10 | //this:代表当前工厂合约的地址 11 | Evidence evidence = new Evidence(evi, this); 12 | newEvidenceEvent(evidence); 13 | return evidence; 14 | } 15 | //获得签证信息 16 | function getEvidence(address addr) public constant returns(string,address[],address[]){ 17 | return Evidence(addr).getEvidence(); 18 | } 19 | 20 | 21 | function addSignatures(address addr) public returns(bool) { 22 | return Evidence(addr).addSignatures(); 23 | } 24 | //初始化合约,导入签名者们的地址(数组传参)为合法签名者地址 25 | //只有合法签名者才有资格进行签证 26 | constructor(address[] evidenceSigners){ 27 | for(uint i=0; i License[]) public licenses; 14 | 15 | event LicenseGranted(bytes32 indexed workHash, uint256 indexed licenseType, address indexed licensee, uint256 validUntil); 16 | event LicenseUpdated(bytes32 indexed workHash, uint256 indexed licenseIndex, uint256 newLicenseType, uint256 newValidUntil); 17 | event LicenseRevoked(bytes32 indexed workHash, uint256 indexed licenseIndex); 18 | 19 | modifier onlyWorkOwner(address workOwner) { 20 | require(tx.origin == workOwner, "只有作品拥有者可以进行操作"); 21 | _; 22 | } 23 | 24 | function grantLicense(bytes32 workHash, address workOwner, uint256 licenseType, address licensee, uint256 validUntil) public onlyWorkOwner(workOwner) { 25 | licenses[workHash].push(License(licenseType, licensee, validUntil, true)); 26 | emit LicenseGranted(workHash, licenseType, licensee, validUntil); 27 | } 28 | 29 | //licenseIndex 默认为0 30 | function updateLicense(bytes32 workHash, address workOwner, uint256 licenseIndex, uint256 newLicenseType, uint256 newValidUntil) public onlyWorkOwner(workOwner) { 31 | require(licenses[workHash][licenseIndex].exists, "许可不存在"); 32 | licenses[workHash][licenseIndex].licenseType = newLicenseType; 33 | licenses[workHash][licenseIndex].validUntil = newValidUntil; 34 | emit LicenseUpdated(workHash, licenseIndex, newLicenseType, newValidUntil); 35 | } 36 | 37 | function revokeLicense(bytes32 workHash, address workOwner, uint256 licenseIndex) public onlyWorkOwner(workOwner) { 38 | require(licenses[workHash][licenseIndex].exists, "许可不存在"); 39 | delete licenses[workHash][licenseIndex]; 40 | emit LicenseRevoked(workHash, licenseIndex); 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /contracts/data_structure/table/Map.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | 3 | import "./LibLinkedList.sol"; 4 | 5 | 6 | 7 | interface DataItem{ 8 | } 9 | 10 | contract EndNode is DataItem{ 11 | } 12 | 13 | contract Pair is DataItem{ 14 | bytes32 key; 15 | DataItem value; 16 | constructor(bytes32 k, DataItem v){ 17 | key = k; 18 | value = v; 19 | } 20 | 21 | function getKey() public returns(bytes32){ 22 | return key; 23 | } 24 | 25 | function getValue()public returns(DataItem){ 26 | return value; 27 | } 28 | 29 | } 30 | 31 | //map 32 | contract Map{ 33 | address constant private NULLADDR = address(0x0); 34 | 35 | using LibLinkedList for LibLinkedList.LinkedList; 36 | LibLinkedList.LinkedList _list; 37 | 38 | mapping(bytes32=>Pair) _nodeSet; 39 | constructor(){ 40 | _nodeSet[bytes32(0)] = new Pair(bytes32(0), new EndNode()); 41 | } 42 | 43 | function insert(bytes32 key, DataItem value)public { 44 | require(_nodeSet[key] == NULLADDR, "the item is already exists"); 45 | Pair pair = new Pair(key, value); 46 | _list.addNode(key); 47 | _nodeSet[key] = pair; 48 | } 49 | 50 | function getValue(bytes32 key)public view returns(DataItem){ 51 | require(_nodeSet[key] != NULLADDR, "the item is not exists"); 52 | return _nodeSet[key].getValue(); 53 | } 54 | 55 | 56 | function getSize()public view returns(uint256){ 57 | return _list.getSize(); 58 | } 59 | 60 | function isEmpty() public view returns(bool){ 61 | return _list.getSize() == 0; 62 | } 63 | 64 | function isExists(bytes32 key) public view returns(bool){ 65 | return _nodeSet[key] != NULLADDR; 66 | } 67 | 68 | function iterate_start() public view returns(Pair){ 69 | return _nodeSet[_list.iterate_start()]; 70 | } 71 | 72 | function iterate_next(Pair iter) public view returns(Pair){ 73 | require(_nodeSet[iter.getKey()] != NULLADDR, "the iter is not exists"); 74 | return _nodeSet[_list.iterate_next(iter.getKey())]; 75 | } 76 | 77 | function can_iterate(Pair iter) public view returns(bool){ 78 | return _list.can_iterate(iter.getKey()); 79 | } 80 | } -------------------------------------------------------------------------------- /contracts/common_tools/privacy_computation/DGHV-HE/DGHV_Homomorphic_Encryption.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity >=0.4.16 < 0.9.0; 3 | 4 | import './LibSafeMathForUint256Utils.sol'; 5 | 6 | contract DGHV_Homomorphic_Encryption { 7 | 8 | // 随机数参数 9 | uint private m = 100; // 线性求余迭代次数 10 | uint private k = 3877; // 乘数 11 | uint private b = 29573; // 增量 12 | 13 | // DGHV参数 14 | uint256 private eta; // 安全参数 15 | uint256 private q; 16 | uint256 private p; // 密钥 17 | 18 | constructor(uint _eta, uint _q, uint _p) public { 19 | require(_p % 2 == 1); // 密钥必须是一个大奇数 20 | eta = _eta; 21 | q = _q; 22 | p = _p; 23 | } 24 | 25 | // 使用线性求余的随机数生成器 26 | function randomGen(uint range, uint seed) private view returns (uint) { 27 | require(range > 0); 28 | uint LCG_random_num = LCG(seed, range); 29 | return uint(keccak256(abi.encodePacked(block.timestamp, LCG_random_num))) % range; 30 | } 31 | 32 | function LCG(uint _seed, uint range) private view returns(uint) { 33 | uint val = _seed; 34 | for (uint256 index = 0; index < m; index++) { 35 | //TODO 内联汇编优化计算 36 | val = (LibSafeMathForUint256Utils.add(LibSafeMathForUint256Utils.mul(k, val), b)) % range; 37 | } 38 | return val; 39 | } 40 | 41 | // 同态加密 42 | function encrypto(uint8 _m) public view returns (uint) { 43 | require(_m == 0 || _m == 1); 44 | // 生成随机数r 45 | uint r = randomGen(8, block.timestamp%1000); 46 | return LibSafeMathForUint256Utils.add(LibSafeMathForUint256Utils.add(_m, 2*r), LibSafeMathForUint256Utils.mul(p, q)); 47 | } 48 | 49 | // 同态解密 50 | function decrypto(uint _c) public view returns (uint) { 51 | return LibSafeMathForUint256Utils.mod(LibSafeMathForUint256Utils.mod(_c, p), 2); 52 | } 53 | 54 | // 同态加法 55 | function HE_Add(uint _c1, uint _c2) public view returns(uint) { 56 | return decrypto(LibSafeMathForUint256Utils.add(_c1, _c2)); 57 | } 58 | 59 | // 同态乘法(可能会溢出) 60 | function HE_Mul(uint _c1, uint _c2) public view returns(uint){ 61 | return decrypto(LibSafeMathForUint256Utils.mul(_c1, _c2)); 62 | } 63 | 64 | 65 | } 66 | -------------------------------------------------------------------------------- /docs/default/proxy/proxy.md: -------------------------------------------------------------------------------- 1 | # 代理执行 2 | 代理执行即代理模式的实现,主要分成三个部分 3 | - 接口合约 4 | 定义了可以被外部调用的方法 5 | - 实现合约 6 | 方法的具体内容实现 7 | - 代理合约 8 | 通过接口合约对实现合约的调用,并在调用前后加入一些额外的逻辑 9 | 10 | 下面以一个唱歌方法的代理调用来描述一下执行的流程 11 | ## 接口合约 12 | 定义了一个singing 方法,入参是singer歌手 13 | ```function singing(address singer) external;``` 14 | 15 | ## 实现合约 16 | 实现合约实现了接口合约中的singsing方法,以记录一个日志事件来代表方法中所做的内容 17 | ```javascript 18 | function singing(address _singer) public override{ 19 | emit SingLog(_singer, now); 20 | } 21 | ``` 22 | 23 | ## 代理合约 24 | 代理合约首先在构造方法中传入被代理合约的实例,通过接口合约进行实例化和方法调用。 25 | 在代理合约中可以在具体方法执行前后进行其他的操作,这里也以两个事件代表,并且通过代理合约,对外暴露的方法名以及具体合约方法的入参,都可以起到一定的修饰作用。 26 | 在此例中,外部看到的代理方法名是``` function proxySing() public ```,而且参数也在代理合约内部进行了处理,调用者不再传此参数。 27 | 在某些情况下如果我们在调用一个方法前必须要做某些准备操作,又或者再调用后要做某些善后工作,都可以使用这种代理的模式。 28 | 29 | 30 | ## 测试合约 31 | 在控制台中,可以测试本代理合约。 32 | ### 创建Sing合约的实例。 33 | 34 | ``` 35 | [group:1]> deploy Sing 36 | transaction hash: 0xa956af77a8bccbf3957e8f0f7b13e284684dc096baf2f63e88d99d9df46ee760 37 | contract address: 0x75adfb58594242bda453f302eb695280cf856c72 38 | currentAccount: 0x22fec9d7e121960e7972402789868962238d8037 39 | ``` 40 | 41 | ### 部署代理合约 42 | ``` 43 | [group:1]> deploy SingProxy 0x75adfb58594242bda453f302eb695280cf856c72 44 | transaction hash: 0xad6fb8b6568e3b575d5c4c4e96b0bf096c6fc5524330eaef6ba7f58dc4240436 45 | contract address: 0x8df5416339b0b55832dabfdf44cecdd81299102c 46 | currentAccount: 0x22fec9d7e121960e7972402789868962238d8037 47 | ``` 48 | 49 | ### 调用代理合约 50 | ``` 51 | [group:1]> call SingProxy 0x8df5416339b0b55832dabfdf44cecdd81299102c proxySing 52 | transaction hash: 0x25ecc3d8584c7e8ac8d169848a4e71a8afce7051d3aacda6b39528f58be16771 53 | --------------------------------------------------------------------------------------------- 54 | transaction status: 0x0 55 | description: transaction executed successfully 56 | --------------------------------------------------------------------------------------------- 57 | Receipt message: Success 58 | Return message: Success 59 | Return values:[] 60 | --------------------------------------------------------------------------------------------- 61 | Event logs 62 | Event: {"ProxyLog":[["0x22fec9d7e121960e7972402789868962238d8037","before proxy do someting"],["0x22fec9d7e121960e7972402789868962238d8037","after proxy do someting"]]} 63 | ``` 64 | 65 | -------------------------------------------------------------------------------- /contracts/business_template/carbon_frugal_evidence/ECDSA.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | 4 | /** 5 | * @title Elliptic curve signature operations 6 | * @dev Based on https://gist.github.com/axic/5b33912c6f61ae6fd96d6c4a47afde6d 7 | * TODO Remove this library once solidity supports passing a signature to ecrecover. 8 | * See https://github.com/ethereum/solidity/issues/864 9 | */ 10 | 11 | library ECDSA { 12 | 13 | /** 14 | * @dev Recover signer address from a message by using their signature 15 | * @param hash bytes32 message, the hash is the signed message. What is recovered is the signer address. 16 | * @param signature bytes signature, the signature is generated using web3.eth.sign() 17 | */ 18 | function recover(bytes32 hash, bytes signature) 19 | internal 20 | pure 21 | returns (address) 22 | { 23 | bytes32 r; 24 | bytes32 s; 25 | uint8 v; 26 | 27 | // Check the signature length 28 | if (signature.length != 65) { 29 | return (address(0)); 30 | } 31 | 32 | // Divide the signature in r, s and v vari ables 33 | // ecrecover takes the signature parameters, and the only way to get them 34 | // currently is to use assembly. 35 | // solium-disable-next-line security/no-inline-assembly 36 | assembly { 37 | r := mload(add(signature, 32)) 38 | s := mload(add(signature, 64)) 39 | v := byte(0, mload(add(signature, 96))) 40 | } 41 | 42 | // Version of signature should be 27 or 28, but 0 and 1 are also possible versions 43 | if (v < 27) { 44 | v += 27; 45 | } 46 | 47 | // If the version is correct return the signer address 48 | if (v != 27 && v != 28) { 49 | return (address(0)); 50 | } else { 51 | // solium-disable-next-line arg-overflow 52 | return ecrecover(hash, v, r, s); 53 | } 54 | } 55 | 56 | /** 57 | * toEthSignedMessageHash 58 | * @dev prefix a bytes32 value with "\x19Ethereum Signed Message:" 59 | * and hash the result 60 | */ 61 | function toEthSignedMessageHash(bytes32 hash) 62 | internal 63 | pure 64 | returns (bytes32) 65 | { 66 | // 32 is the length in bytes of hash, 67 | // enforced by the type signature above 68 | return keccak256( 69 | abi.encodePacked("\x19Ethereum Signed Message:\n32", hash) 70 | ); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /contracts/base_type/array/TwoDArrayDemo.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | pragma experimental ABIEncoderV2; 3 | 4 | import "./Lib2DArrayForUint256.sol"; 5 | 6 | contract TwoDArrayDemo { 7 | 8 | uint256[][] private array; 9 | uint256[][] private array2; 10 | uint256[] val = [1,2]; 11 | uint256[] val2 = [3, 4, 5]; 12 | uint256[] val3 = [6, 7, 8, 9]; 13 | 14 | function addAndGetValue(uint256 row, uint256 col) public view returns (uint256) { 15 | array = new uint256[][](0); 16 | Lib2DArrayForUint256.addValue(array,val); 17 | Lib2DArrayForUint256.addValue(array,val2); 18 | // (1,1) => expected Return values:(4) 19 | return Lib2DArrayForUint256.getValue(array,row,col); 20 | } 21 | 22 | function firstIndexOf(uint256 key) public view returns (bool, uint256, uint256) { 23 | array = new uint256[][](0); 24 | Lib2DArrayForUint256.addValue(array,val); 25 | // (2) => expected Return values:(true, 0, 0) 26 | return Lib2DArrayForUint256.firstIndexOf(array,key); 27 | } 28 | 29 | 30 | function setValue(uint256 row, uint256 col, uint256 key) public view returns (uint256[][]) { 31 | array = new uint256[][](0); 32 | Lib2DArrayForUint256.addValue(array,val); 33 | Lib2DArrayForUint256.addValue(array,val2); 34 | // (1, 0, 9) => expected Return values:([[1, 2] [9, 4, 5] ] ) 35 | return Lib2DArrayForUint256.setValue(array,row,col,key); 36 | } 37 | 38 | function removeByIndex(uint256 index) public view returns (uint256[][]) { 39 | array = new uint256[][](0); 40 | Lib2DArrayForUint256.addValue(array,val); 41 | Lib2DArrayForUint256.addValue(array,val2); 42 | Lib2DArrayForUint256.addValue(array,val3); 43 | // 1 => expected Return values:([[1, 2] [6, 7, 8, 9] ] ) 44 | return Lib2DArrayForUint256.removeByIndex(array,index); 45 | 46 | } 47 | 48 | function extend() public view returns (uint256[][]) { 49 | array = new uint256[][](0); 50 | array2 = new uint256[][](0); 51 | Lib2DArrayForUint256.addValue(array,val); 52 | Lib2DArrayForUint256.addValue(array,val2); 53 | Lib2DArrayForUint256.addValue(array2,val3); 54 | // expected Return values:([[1, 2] [3, 4, 5] [6, 7, 8, 9] ] ) 55 | return Lib2DArrayForUint256.extend(array,array2); 56 | } 57 | } -------------------------------------------------------------------------------- /docs/business_template/medicalCase/docCase.md: -------------------------------------------------------------------------------- 1 | # 基于区块链的分级诊疗数据共享案例 2 | 3 | ***★知识要点★*** 4 | 5 | - 研究背景 6 | - 研究目标 7 | - 平台设计 8 | 9 | 10 | 11 | 12 | ## 1. 研究背景 13 | 14 | 分级诊疗是合理配置医疗资源、改善民生,提高 15 | 全民健康水平的重要举措。2015年,国务院办公厅就 16 | 印发了《关于推进分级诊疗制度建设的指导意见》。 17 | 部署加快推进分级诊疗制度建设。构建医疗机构间的 18 | 数据共享是推进分级诊疗的关键。中共中央国务院在 19 | 《“健康中国2030”规划纲要》中就强调要完善医疗服 20 | 务体系、创新医疗服务供给模式,建立信息共享、互 21 | 联互通机制。 22 | ## 2. 现有平台存在的问题 23 | 24 | 1. 各级医院间无法建立协商一致的标准,导致数据共享难。 25 | 2. 各级医院间数据传输不能确保信息的可靠性及可追溯性,导致医患矛盾 26 | 解决难。 27 | 3. 患者在不同医院诊疗产生的信息极易泄露,导致患者维护病历所有权难 28 | 29 | ![image-20211209152955771](./assets/1.png) 30 | 31 | ## 3. 研究目标 32 | 33 | 基于区块链的技术特点,探索应用区块链技术解决医疗机构分级诊 34 | 疗平台存在的数据打通和数据安全等技术问题,为区块链技术应用于分 35 | 级诊疗提供典型案例,为区块链技术的落地及相关研究提供一定的借鉴 36 | 意义。 37 | ## 4. 平台设计 38 | 利用联盟链将各级医院组成医院联盟,每家医院为一个全节点,让不同级别医院共同参与管理, 39 | 结合IPFS分布式存储,实现医疗数据共享;在跨院就诊时,历史医疗信息由患者授权,有效保证患者对自 40 | 身病历的控制权;此外,患者分级诊疗流程记录在链上存证。 41 | ![image-20211209152955771](./assets/2.png) 42 | ## 5. 系统架构 43 | 1. 页面展示:面向患者和医生,可供患者上传、查询病历及授权记录,可供医生创建和查看患者病历,查看病历前需申请患者授权。 44 | 2. 业务设计:收集来自前端以及合约层的数据,进行增加、更新等处理,实现对链上链下存储系统接口的调用,以及对 45 | 数据加密操作。 46 | 3. 合约设计:用于执行链上关键业务逻辑,本系统主要包含病历关键信息的记录和授权信息的记录两个核心智能合约。 47 | 4. 底层存储:采用链上链下结合存储数据。链上存储病历关键信息和授权信息,链下利用IPFS存储病历完整信息,其余数据由本地MySQL数据库存储。 48 | ![image-20211209152955771](./assets/3.png) 49 | ## 6. 技术架构 50 | ![image-20211209152955771](./assets/4.png) 51 | ## 7. 系统功能 52 | ![image-20211209152955771](./assets/5.png) 53 | 54 | ### 7.1 公共功能 55 | 对于初次使用系统的患者,需要通过注册登录模块,在注册界面对个人信息进行登记,创建患者用户角色。就诊患者或 56 | 医生使用本系统时,必须通过账号,选择所属的医院进行登录。此外,用户可以通过基本信息管理模块,对个人信息进行查 57 | 看和修改。 58 | ### 7.2 患者功能 59 | 对于患者而言,主要包括病历管理以及病历授权两个模块。病历信息管理模块的主要功能是让患者能够上传到区块链上 60 | 进行存证,以及查询自己病历。病历授权管理模块的功能包括对医生端提交的申请进行处理,以及提供信息授权列表,让患 61 | 者能够知晓电子病历的授权情况。 62 | ### 7.3 医生功能 63 | 医疗就诊模块是对就诊患者进行建档,生成电子病历。病历调阅模块可以实现不同医院的医生查看患者的医疗信息,在这个过 64 | 程中,医生需要向患者发出申请。 65 | ## 8.业务流程 66 | ![image-20211209152955771](./assets/6.png) 67 | 以患者跨两级医院就诊为例,关键流程包括患者病历信息加密上链、跨医院就诊授权医生访问病历、授权记录上链存证。 68 | ### 8.1 病历关键信息上链 69 | ![image-20211209152955771](./assets/7.png) 70 | 患者在一级医院就诊后,医生负责创建病历,待双方确认无误后,完整病历由患者上传,存储至IPFS 71 | 中,对存储返回的地址进行AES对称加密,把加密后的存储地址存在链上,完成就诊关键信息上链。 72 | ### 8.2 申请授权 73 | ![image-20211209152955771](./assets/8.png) 74 | 患者在转到二级医院就诊时,即跨医院就诊。医生查看患者病历前需要先提出申请,待患者同意后, 75 | 二级医院医生方可查阅患者病历,从而有效实现了病人对自己病历的控制权,不同医院间的相互查阅病历, 76 | 有效实现了数据共享。 77 | ### 8.3 授权记录存证 78 | ![image-20211209152955771](./assets/9.png) 79 | 患者的每次授权行为都会记录在链上存证,使得患者更加清晰病历的去向,就诊全流程记录与存证, 80 | 有效减少医患矛盾产生。 -------------------------------------------------------------------------------- /contracts/base_type/bits/TestBits.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.24 <0.6.11; 2 | 3 | import "./LibBits.sol"; 4 | 5 | contract TestBits { 6 | 7 | function testAnd() public view returns(bytes1 ){ 8 | bytes1 a = 1; 9 | bytes1 b = 5; 10 | bytes1 result = LibBits.and(a, b);//Expected to be 1 11 | return result; 12 | } 13 | 14 | function testOr() public view returns(bytes1 ){ 15 | bytes1 a = 2; // 0x010 16 | bytes1 b = 5; // 0x101 17 | bytes1 result = LibBits.or(a, b);//Expected to be 7, 0x111 18 | return result; 19 | } 20 | 21 | function testXor() public view returns(bytes1 ){ 22 | byte a = 3; // 0x011 23 | byte b = 5; // 0x101 24 | bytes1 result = LibBits.xor(a, b); //Expected to be 6, 0x110 25 | return result; 26 | } 27 | 28 | function testNegate() public view returns(bytes1){ 29 | bytes1 r = LibBits.negate(5);//Expected to be -6 0x00000101 -> 0x11111010 30 | return r; 31 | } 32 | 33 | function testShiftLeft() public view returns(bytes1){ 34 | bytes1 r = LibBits.shiftLeft(2,3);//Expected to be 16, 0x00000010 -> 0x00010000 35 | return r; 36 | } 37 | 38 | function testShiftRight() public view returns(bytes1){ 39 | bytes1 r = LibBits.shiftRight(15,3);//Expected to be 1, 0x00001111 -> 0x00000001 40 | return r; 41 | } 42 | 43 | function testGetLastN() public view returns(bytes1){ 44 | bytes1 r = LibBits.getLastN(60,3);//Expected to be 4 0x00111100 -> 0x00000100 45 | return r; 46 | } 47 | 48 | function getFirstN() public view returns(bytes1){ 49 | byte r = LibBits.getFirstN(60,3);//Expected to be 32, 0x00111100 -> 0x00100000 50 | return r; 51 | } 52 | 53 | function testAllOnes() public view returns(bytes1){ 54 | byte r = LibBits.allOnes();//Expected to be 255 55 | return r; 56 | } 57 | 58 | function testGetBit() public view returns(bool){ 59 | bool r = LibBits.getBit(3,2);//Expected to be 1 60 | return r; 61 | } 62 | 63 | function testSetBit() public view returns(bytes1){ 64 | byte r = LibBits.setBit(17,2);//Expected to be 19, 0x00010001 -> 0x00010011 65 | return r; 66 | } 67 | 68 | function testClearBit() public view returns(bytes1){ 69 | byte r = LibBits.clearBit(17,5);//Expected to be 1 70 | return r; 71 | } 72 | } -------------------------------------------------------------------------------- /contracts/business_template/traceability/TraceabilityFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | pragma experimental ABIEncoderV2; 3 | 4 | import "./Traceability.sol"; 5 | 6 | contract TraceabilityFactory{ 7 | struct GoodsTrace{ 8 | Traceability trace; 9 | bool valid; 10 | } 11 | mapping(bytes32=>GoodsTrace) private _goodsCategory; 12 | 13 | event newTraceEvent(bytes32 goodsGroup); 14 | 15 | //Create traceability commodity category 16 | function createTraceability(bytes32 goodsGroup) public returns(Traceability) { 17 | require(!_goodsCategory[goodsGroup].valid,"The trademark already exists" ); 18 | Traceability category = new Traceability(goodsGroup); 19 | _goodsCategory[goodsGroup].valid = true; 20 | _goodsCategory[goodsGroup].trace = category; 21 | emit newTraceEvent(goodsGroup); 22 | return category; 23 | } 24 | 25 | function getTraceability(bytes32 goodsGroup) private view returns(Traceability) { 26 | require(_goodsCategory[goodsGroup].valid,"The trademark has not exists" ); 27 | return _goodsCategory[goodsGroup].trace; 28 | } 29 | //Create traceability products 30 | function createTraceGoods(bytes32 goodsGroup, uint64 goodsId) public returns(Goods) { 31 | Traceability category = getTraceability(goodsGroup); 32 | return category.createGoods(goodsId); 33 | } 34 | 35 | //Change product status 36 | function changeTraceGoods(bytes32 goodsGroup, uint64 goodsId, int16 goodsStatus, string memory remark) public { 37 | Traceability category = getTraceability(goodsGroup); 38 | category.changeGoodsStatus(goodsId, goodsStatus, remark); 39 | } 40 | 41 | //Query the current status of goods 42 | function getStatus(bytes32 goodsGroup, uint64 goodsId) public view returns(int16) { 43 | Traceability category = getTraceability(goodsGroup); 44 | return category.getStatus(goodsId); 45 | } 46 | 47 | //The whole process of querying goods 48 | function getTraceInfo(bytes32 goodsGroup, uint64 goodsId) public view returns(Goods.TraceData[]) { 49 | Traceability category = getTraceability(goodsGroup); 50 | return category.getGoods(goodsId).getTraceInfo(); 51 | } 52 | 53 | function getGoodsGroup(string memory name) public pure returns (bytes32) { 54 | return keccak256(abi.encode(name)); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /contracts/business_template/CharityFund/CharityLogistics.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.25; 2 | pragma experimental ABIEncoderV2; 3 | 4 | import "./PublicData.sol"; 5 | import "./RolesAuth.sol"; 6 | 7 | contract CharityLogistics is PublicData{ 8 | 9 | RolesAuth private rolesAuth; 10 | 11 | // 物流公司的结构体 12 | struct Logistics { 13 | uint256 logisticsId; // 物流公司ID 14 | string logisticsName; // 物流公司名称 15 | address logisticsAddress; // 物流公司的地址 16 | int status; // 物流公司的状态 17 | } 18 | 19 | // 物流公司的ID 20 | uint256 logisticsCount; 21 | // 所有物流公司的地址 22 | address[] logisticsAddress; 23 | // 地址映射物流公司的详细信息 24 | mapping(address => Logistics) logisticsMap; 25 | // 修饰符函数 26 | modifier _AuthLogistic { 27 | require(rolesAuth.hasLogistic(msg.sender),"没有权限"); 28 | _; 29 | } 30 | 31 | 32 | 33 | constructor() public { 34 | rolesAuth = new RolesAuth(); 35 | } 36 | 37 | // 注册物流公司 38 | function registerLogistics(string memory _logisticsName) public returns(Logistics) { 39 | require(logisticsMap[msg.sender].status == 0,"当前的物流公司已经注册"); 40 | logisticsCount++; 41 | uint256 _logisticsId = logisticsCount; 42 | Logistics storage _logistic = logisticsMap[msg.sender]; 43 | _logistic.logisticsId = _logisticsId; 44 | _logistic.logisticsName = _logisticsName; 45 | _logistic.logisticsAddress = msg.sender; 46 | _logistic.status = 1; 47 | rolesAuth.addLogistic(msg.sender); 48 | 49 | logisticsAddress.push(msg.sender); 50 | 51 | return _logistic; 52 | } 53 | 54 | 55 | /** 56 | * @dev 物流公司进行物资发货操作 57 | * @param _transacionId 待发送的公益捐助交易 ID 58 | * @return 发送后的公益捐助交易信息 59 | * 60 | **/ 61 | function dispatch(uint256 _transacionId) public _AuthLogistic returns(Transaction){ 62 | require(transactionMap[_transacionId].transacStatus == TransacStatus.SHIPMENT,"当前物流未出货"); 63 | if (transactionMap[_transacionId].isTransport){ 64 | Transaction storage _transacion = transactionMap[_transacionId]; 65 | _transacion.transacStatus = TransacStatus.LOGISTICS; 66 | _transacion.sources.push(msg.sender); 67 | emit Dispathed(msg.sender,_transacionId); 68 | return _transacion; 69 | } 70 | return; 71 | } 72 | } -------------------------------------------------------------------------------- /docs/business_template/RewardPoint.md: -------------------------------------------------------------------------------- 1 | ## 积分模板背景说明 2 | 3 | 在区块链的业务方案中,积分系统是非常常见的一种场景。 4 | 5 | 基于智能合约的积分系统,支持多家机构发行、用户注册、积分消费、积分销户、用户销户等多种功能。 6 | 7 | 8 | ## 场景说明 9 | 10 | 典型的积分场景包括了以下角色: 11 | 12 | - 发行者:发行积分。 13 | - 用户:获得和消费积分,还可实现积分的转账。 14 | - 管理者:积分系统的管理者。 15 | 16 | 积分系统中包括了以下功能: 17 | 18 | - 创建积分系统 19 | - 注册:用户注册会员,只有经过注册的用户才能获得和消费积分。 20 | - 销户: 用户销户。只有积分为0的用户才能正常销户。 21 | - 添加发行者: 发行者具有发行积分的权利。 22 | - 发行积分: 支持定向发送到某个积分账户。 23 | - 删除发行者: 发行者可以注销自身的发行积分的权利。 24 | - 转账: 支持用户积分的互转和消费等。 25 | - 积分销毁: 用户可以销毁自己的积分。 26 | 27 | 28 | ## 接口 29 | 30 | 主体为3个合约: Admin、RewardPointController、RewardPointData。 31 | 32 | 其中Admin为管理合约,提供合约部署和管理的接口: 33 | 34 | - 构造函数: 部署合约。默认部署合约的外部账户为资产发行者。 35 | - upgradeVersion(address newVersion) 更新数据的controller最新地址 36 | - _dataAddress() 查询数据合约的地址 37 | - _controllerAddress() 查询控制合约的地址 38 | 39 | RewardPointController 提供了合约控制相关的接口: 40 | 41 | - addIssuer(address account) 添加资产发行者。只有资产发行者可以添加新的资产发行者。 42 | - issue(address account, uint256 value) 发行积分 43 | - isIssuer(address account) 判断是否是资产发行者。 44 | - addIssuer(address account) 添加发行者,只能由发行者添加。 45 | - renounceIssuer() 撤销发行者,只能撤销自己。 46 | - register() 普通用户账户注册。 47 | - unregister() 普通用户账户注销。 48 | - isRegistered(address addr) 判断普通用户是否注册。 49 | - balance(address addr) 查询普通用户的积分。 50 | - transfer(address toAddress, uint256 value) 往目标账户转积分 51 | - destroy(uint256 value) 销毁自己账户中的指定数量的积分 52 | 53 | RewardPointData提供了底层的数据存储,不对外暴露直接访问的接口。 54 | 55 | 其他的合约为工具或辅助合约。 56 | 57 | ## 使用示例 58 | 59 | 整体流程如下: 60 | 61 | 合约初始化: 62 | 63 | - 管理员部署Admin合约, 管理员在控制台中输入『deploy Admin』部署合约。 64 | - 管理员调用Admin合约的_controllerAddress()函数,获得RewardPointController合约的地址。 65 | 66 | 资产发行者维护: 67 | 68 | - 管理员使用 RewardPointController 合约的地址,加载RewardPointController合约。 69 | - 管理员默认为资产发行者,可以通过addIssuer添加其他发行者,通过renounceIssuer接口撤销自己发行者的权限。 70 | - 通过isIssuer接口查询某个用户是否为资产发行者。 71 | 72 | 账户注册: 73 | 74 | - 用户使用管理员发放的 RewardPointController 合约的地址,加载RewardPointController合约。 75 | - 用户使用RewardPointController合约中的register()接口注册账户。 76 | - 通过isRegistered判断是否已注册。 77 | 78 | 积分发行: 79 | 80 | - 用户使用RewardPointController的isIssuer函数判断自己是否为积分发行者。 81 | - 如果为是,用户通过issue接口定向发现积分。 82 | 83 | 积分操作: 84 | 85 | - 用户通过transfer接口实现积分转账。 86 | - 用户通过balance接口查询积分余额。 87 | - 用户通过destroy接口实现指定数额的账户积分的注销。 88 | 89 | 账户销户: 90 | 91 | - 用户通过unregister接口销户,只有积分余额为0的账户可以直接销户。 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /contracts/business_template/reward_point/RewardPointData.sol: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * */ 16 | 17 | pragma solidity ^0.4.25; 18 | 19 | import "./BasicAuth.sol"; 20 | import "./IssuerRole.sol"; 21 | 22 | contract RewardPointData is BasicAuth, IssuerRole { 23 | 24 | mapping(address => uint256) private _balances; 25 | mapping(address => bool) private _accounts; 26 | uint256 public _totalAmount; 27 | string public _description; 28 | address _latestVersion; 29 | 30 | constructor(string memory description) public { 31 | _description = description; 32 | } 33 | 34 | modifier onlyLatestVersion() { 35 | require(msg.sender == _latestVersion); 36 | _; 37 | } 38 | 39 | function upgradeVersion(address newVersion) public { 40 | require(msg.sender == _owner); 41 | _latestVersion = newVersion; 42 | } 43 | 44 | 45 | function setBalance(address a, uint256 value) onlyLatestVersion public returns (bool) { 46 | _balances[a] = value; 47 | return true; 48 | } 49 | 50 | function setAccount(address a, bool b) onlyLatestVersion public returns (bool) { 51 | _accounts[a] = b; 52 | return true; 53 | } 54 | 55 | function setTotalAmount(uint256 amount) onlyLatestVersion public returns (bool) { 56 | _totalAmount = amount; 57 | return true; 58 | } 59 | 60 | function getAccountInfo(address account) public view returns (bool, uint256) { 61 | return (_accounts[account], _balances[account]); 62 | } 63 | 64 | function hasAccount(address account) public view returns(bool) { 65 | return _accounts[account]; 66 | } 67 | 68 | function getBalance(address account) public view returns (uint256) { 69 | return _balances[account]; 70 | } 71 | 72 | } 73 | 74 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![GitHub All Releases](https://img.shields.io/github/downloads/WeBankBlockchain/SmartDev-Contract/total.svg)](https://github.com/WeBankBlockchain/SmartDev-Contract) 2 | 3 | 4 | # 组件介绍 5 | 6 | 智能合约库模板,涵盖了从基础类型到上层业务的常见代码,用户可根据实际需要进行参考、复用。 7 | 8 | 9 | ## 环境要求 10 | 11 | | 依赖软件 | 说明 |备注| 12 | | --- | --- | --- | 13 | | Solidity | 0.4.25-0.6.10 | | 14 | | Git | 下载需要使用Git | | 15 | 16 | ## 文档 17 | - [**中文**](https://smartdev-doc.readthedocs.io/zh_CN/latest/docs/WeBankBlockchain-SmartDev-Contract/index.html) 18 | - [**快速开始**](https://smartdev-doc.readthedocs.io/zh_CN/latest/docs/WeBankBlockchain-SmartDev-Contract/quick_start.html) 19 | ## 贡献代码 20 | 欢迎参与本项目的社区建设: 21 | - 如项目对您有帮助,欢迎点亮我们的小星星(点击项目左上方Star按钮)。 22 | - 欢迎提交代码(Pull requests)。 23 | - [提问和提交BUG](https://github.com/WeBankBlockchain/SmartDev-Contract/issues)。 24 | - 如果发现代码存在安全漏洞,请在[这里](https://security.webank.com)上报。 25 | 26 | 27 | ![](https://media.githubusercontent.com/media/FISCO-BCOS/LargeFiles/master/images/QR_image.png) 28 | 29 | ## 合约征集令 30 | 为了覆盖和满足日益丰富的开发者和行业的诉求,现面向广大爱好区块链开发者、合作伙伴发布智能合约代码征集令。 31 | 32 | 本次活动基于Solidity语言征集智能合约代码。**版本范围:0.4.25-0.6.10** 。 33 | 34 | 为了便于参与,我们拟定了部分任务列表(如下表所示),每位参与者可以选择自己感兴趣的任务进行领取并开发,也可以基于具体的业务场景作为开发任务,原则上不做代码功能的限定。同时,由于每一个任务为概述性的描述,包含的内容较多,所以每个任务可由多位参与者领取。 35 | 36 | |任务ID | 任务类别| 任务名称 | 任务描述| 37 | | --- | --- | --- | --- | 38 | |1 | 原有合约功能 | 原有合约库优化和增强 |针对智能合约库中现有合约的功能进行补充和增强,如针对不同数据类型,提供数组、字符串、地址、数学计算等操作。| 39 | |2 | 原有合约功能 | 数学运算增强 |提供开方、指数、对数等运算。| 40 | |3 | 新增功能模块 | 计数器操作 | 提供基于solidity的计数器功能| 41 | |4 | 新增功能模块 | 证件号码验证 | 针对大陆18或15位,港、澳8位, 台10位身份证件号码合法性验证| 42 | |5 | 新增功能模块 | 数据实体封装 | 对实体属性封装为合约,并提供get/set等属性操作方法| 43 | |6 | 新增功能模块 | 匿名投票 |实现匿名投票,在投票期间各票信息以密文形式上链,在投票结束后才公开| 44 | |7 | 新增功能模块 | 多方签名 |提供一个抽象层面的多方签名功能,可以应用于多方认证的场景| 45 | |8 | 新增功能模块 | 多方投票 |提供多方投票功能,投票策略可多样化| 46 | |9 | 新增场景 | 版权保护 |包括但不限于文化、专利、艺术品、数字内容的确权、鉴权等方案。| 47 | |10 | 新增场景 | 金融 |对于供应链金融、征信、反洗钱等金融场景,提供相关的智能合约通用化模板。| 48 | |11 | 新增场景 | 慈善公益 |基于慈善公益,提供但不限于善款追溯、善行激励等场景的使用场景| 49 | |12 | 新增场景 | 共享经济 |针对共享经济中的痛点,提供区块链的解决方案,例如租房、图书共享等使用场景。| 50 | |13 | 文档教程 | 智能合约教程 |原创的各类智能合约开发教程、分享。| 51 | |14 | 文档教程 | 智能合约常见漏洞集 |各类型漏洞合约,帮助增强开发人员漏洞意识,提升智能合约安全性。| 52 | 53 | 以上任务仅供参考。 54 | 55 | 我们欢迎所有Solidity智能合约相关的贡献。 56 | 57 | 【报名方式】 58 | 扫描下方二维码,回复:智能合约,加小助手微信入活动社群,填写在线报名表。 59 | 60 | ![微众银行小助手二维码](./webank_blockchain_qrcode.png) 61 | 62 | ## License 63 | ![license](http://img.shields.io/badge/license-Apache%20v2-blue.svg) 64 | 65 | 开源协议为[Apache License 2.0](http://www.apache.org/licenses/). 详情参考[LICENSE](../LICENSE)。 66 | 67 | 68 | 69 | 70 | --------------------------------------------------------------------------------