├── index.html ├── .gitignore ├── .vscode └── settings.json ├── public ├── favicon.ico ├── robots.txt ├── manifest.json └── index.html ├── src ├── assets │ ├── cupIcon.png │ ├── screenshot.png │ ├── refresh.svg │ └── tronLogo.svg ├── index.css ├── index.js ├── App.js └── components │ ├── Inputs.module.css │ ├── Refresh.js │ ├── Refresh.module.css │ ├── TronlinkFunctions.js │ ├── NetworkStates.module.css │ ├── TronlinkFunctions.module.css │ ├── NetworkStates.js │ ├── Inputs.js │ ├── ContractExtracted.module.css │ ├── ContractExtracted.js │ ├── Card.module.css │ └── Card.js ├── contracts ├── Array_Demo.sol └── Many_Inputs.sol ├── package.json └── README.md /index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "git.ignoreLimitWarning": true 3 | } -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibnzUK/Smart-Contract-GUI/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /src/assets/cupIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibnzUK/Smart-Contract-GUI/HEAD/src/assets/cupIcon.png -------------------------------------------------------------------------------- /src/assets/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibnzUK/Smart-Contract-GUI/HEAD/src/assets/screenshot.png -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | html { 6 | font-family: sans-serif; 7 | 8 | } 9 | 10 | body { 11 | margin: 0; 12 | 13 | } -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | import './index.css'; 5 | import App from './App'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "theme_color": "#000000", 7 | "background_color": "#ffffff" 8 | } 9 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Card from './components/Card'; 3 | 4 | function App() { 5 | return ( 6 |
7 | 8 |
9 | ); 10 | } 11 | 12 | export default App; 13 | -------------------------------------------------------------------------------- /src/components/Inputs.module.css: -------------------------------------------------------------------------------- 1 | .functionInput { 2 | border: none; 3 | padding: 0.6em; 4 | text-align: center; 5 | width: 20em; 6 | margin-right: 0.5em; 7 | height: auto; 8 | margin: 0.1em; 9 | 10 | } 11 | .functionInput:focus { 12 | outline: none; 13 | 14 | } 15 | 16 | .functionInput::placeholder { 17 | color: rgba(43, 43, 43, 0.527); 18 | } 19 | -------------------------------------------------------------------------------- /src/components/Refresh.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import classes from './Refresh.module.css'; 3 | import refresh from '../assets/refresh.svg'; 4 | 5 | const Refresh = (props) => { 6 | return ( 7 | 10 | ); 11 | }; 12 | 13 | export default Refresh; 14 | -------------------------------------------------------------------------------- /contracts/Array_Demo.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.23 <0.6.0; 2 | 3 | // Smart contract example to test array for payable and non payable functions for SMART CONTRACT GUI 4 | // Jutinas Kairys 5 | // 20.June.2021 6 | 7 | contract Array_Demo { 8 | string[] public myArray = [ 9 | "a", 10 | "b", 11 | "c" 12 | ]; 13 | 14 | function newEntry (string memory _addToarray) public { 15 | myArray.push(_addToarray); 16 | } 17 | 18 | function arrayLength() public view returns (uint) { 19 | return myArray.length; 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /src/components/Refresh.module.css: -------------------------------------------------------------------------------- 1 | .refresh { 2 | height: 2em; 3 | margin-top: 0.2em; 4 | margin-right: 0.2em; 5 | border-radius: 1em; 6 | } 7 | .refresh:active { 8 | outline: none; 9 | } 10 | 11 | .refreshBtn { 12 | background-color: rgba(255, 255, 255, 0); 13 | border: none; 14 | margin: 0; 15 | padding: 0; 16 | border-radius: 1em; 17 | outline: none; 18 | } 19 | 20 | .refreshBtn:hover { 21 | background-color: rgba(255, 255, 255, 0); 22 | } 23 | 24 | .refreshBtn .refresh { 25 | width: 24px; 26 | height: 24px; 27 | transition: all 0.4s ease-in-out; 28 | } 29 | 30 | .refreshBtn:hover .refresh { 31 | transform: rotate(-60deg) scale(1.2); 32 | cursor: pointer; 33 | } 34 | -------------------------------------------------------------------------------- /src/components/TronlinkFunctions.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import classes from './TronlinkFunctions.module.css'; 3 | import cupIcon from '../assets/cupIcon.png'; 4 | 5 | const TronlinkFunctions = (props) => { 6 | return ( 7 |
8 | 18 |
19 | ); 20 | }; 21 | 22 | export default TronlinkFunctions; 23 | -------------------------------------------------------------------------------- /src/components/NetworkStates.module.css: -------------------------------------------------------------------------------- 1 | .button3states { 2 | margin: 0.4em; 3 | font-size: 0.9em; 4 | } 5 | 6 | .state1 { 7 | margin-top: 0.5em; 8 | background-color: rgba(255, 255, 255, 0); 9 | border: none; 10 | color: #a7a7a7; 11 | margin-right: 0.3em; 12 | width: 5em; 13 | height: 1.2em; 14 | padding: 0px; 15 | border-radius: 0; 16 | } 17 | .state1:hover { 18 | background: none; 19 | color: #4e4e4e; 20 | cursor: pointer; 21 | } 22 | .state2:hover { 23 | background: none; 24 | color: #ec0606; 25 | cursor: pointer; 26 | } 27 | .state1:focus { 28 | outline: none; 29 | } 30 | .state2:focus { 31 | outline: none; 32 | } 33 | 34 | .state2 { 35 | background-color: rgba(255, 255, 255, 0); 36 | border-top: none; 37 | border-left: none; 38 | border-right: none; 39 | border-bottom: solid rgb(231, 3, 3) 2px; 40 | color: #ec0606; 41 | margin-right: 0.3em; 42 | width: 5em; 43 | height: 1.2em; 44 | padding: 0px; 45 | border-radius: 0; 46 | } 47 | -------------------------------------------------------------------------------- /src/components/TronlinkFunctions.module.css: -------------------------------------------------------------------------------- 1 | .experimental { 2 | margin-top: 15em; 3 | margin-bottom: 4em; 4 | display: flex; 5 | justify-content: center; 6 | } 7 | 8 | .buyCoffeBtn { 9 | /* background-color: none; */ 10 | background: none; 11 | border: none; 12 | font-size: 1em; 13 | 14 | padding: 0; 15 | display: flex; 16 | flex-direction: row; 17 | align-items: center; 18 | align-items: center; 19 | } 20 | 21 | .buyCoffeBtn p { 22 | color: rgb(29, 19, 19); 23 | font-weight: 300; 24 | font-size: 1em; 25 | font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 26 | padding-bottom: 0.1em; 27 | } 28 | 29 | .buyCoffeBtn:hover { 30 | cursor: pointer; 31 | } 32 | 33 | .buyCoffeBtn:focus { 34 | outline: none; 35 | } 36 | 37 | .buyCoffeBtn p .trx { 38 | color: rgb(255, 17, 17); 39 | font-weight: 300; 40 | font-size: 0.8em; 41 | font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 42 | padding-bottom: 0.1em; 43 | } 44 | 45 | .cupIcon { 46 | height: 1em; 47 | margin-right: 0.3em; 48 | } 49 | -------------------------------------------------------------------------------- /src/components/NetworkStates.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import classes from './NetworkStates.module.css'; 3 | 4 | const NetworkStates = (props) => { 5 | return ( 6 |
7 | 17 | 18 | 28 | 38 |
39 | ); 40 | }; 41 | 42 | export default NetworkStates; 43 | -------------------------------------------------------------------------------- /contracts/Many_Inputs.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.23 <0.6.0; 2 | 3 | // Smart contract example to test different inputs and functions for SMART CONTRACT GUI 4 | // Jutinas Kairys 5 | // 20.June.2021 6 | 7 | contract Many_Inputs { 8 | 9 | string public message; 10 | uint256 public myNumber = 1; 11 | address public owner; 12 | 13 | function setMessage(string memory newMessage) public { 14 | message = newMessage; 15 | } 16 | 17 | function getMessage() public view returns (string memory) { 18 | return message; 19 | } 20 | 21 | function changeData() public { 22 | myNumber = myNumber +3; 23 | } 24 | 25 | function testInputs(string memory _stringInput, uint256 _numberInput, address _addressInput) public { 26 | myNumber = _numberInput; 27 | message = _stringInput; 28 | owner = _addressInput; 29 | } 30 | 31 | function manyInputs(string memory s1, string memory s2, string memory s3, string memory s4, string memory s5) public { 32 | message = string(abi.encodePacked("s1: ", s1, ",", " s2: ", s2, ",", " s3: ", s3, ",", " s4: ", s4, ",", " s5: ", s5)); 33 | } 34 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "smart-contract-gui", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^4.2.4", 7 | "@testing-library/react": "^9.4.1", 8 | "@testing-library/user-event": "^7.2.1", 9 | "react": "^17.0.2", 10 | "react-dom": "^17.0.2", 11 | "react-scripts": "4.0.3", 12 | "tronweb": "^3.2.6" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": "react-app" 22 | }, 23 | "browserslist": { 24 | "production": [ 25 | ">0.2%", 26 | "not dead", 27 | "not op_mini all" 28 | ], 29 | "development": [ 30 | "last 1 chrome version", 31 | "last 1 firefox version", 32 | "last 1 safari version" 33 | ] 34 | }, 35 | "main": "index.js", 36 | "devDependencies": {}, 37 | "author": "Justinas Kairys", 38 | "license": "ISC", 39 | "description": "Experimental React, Blockchain project to provide graphical user interface for smart contracts on Tron network" 40 | } 41 | -------------------------------------------------------------------------------- /src/assets/refresh.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 16 | 17 | -------------------------------------------------------------------------------- /src/assets/tronLogo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 19 | 20 | -------------------------------------------------------------------------------- /src/components/Inputs.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useRef } from 'react'; 2 | import classes from './Inputs.module.css'; 3 | 4 | const Inputs = (props) => { 5 | // console.log(props.types.abi.stateMutability); 6 | 7 | const nameInputRef = useRef(); 8 | const [inputValue, setInputValue] = useState(''); 9 | let inputs = props.inputs; 10 | 11 | const inputChangeHandler = (event) => { 12 | event.preventDefault(); 13 | const enteredName = nameInputRef.current.value; 14 | 15 | 16 | if (props.types.abi.stateMutability === 'View') { 17 | 18 | setInputValue(event.target.value); 19 | inputs[0] = { 20 | name: nameInputRef.current.name, 21 | type: props.placeholder, 22 | value: enteredName, 23 | ftype: 'View' 24 | }; 25 | 26 | // console.log(inputs); 27 | props.inputChanger(inputs); 28 | 29 | } else { 30 | const valueForElemnt = inputs.find( 31 | ({ name }) => name === nameInputRef.current.name 32 | ); 33 | 34 | const index = inputs.findIndex((element) => element === valueForElemnt); 35 | 36 | inputs[index] = { 37 | name: nameInputRef.current.name, 38 | type: props.placeholder, 39 | value: enteredName, 40 | }; 41 | 42 | setInputValue(event.target.value); 43 | props.inputChanger(inputs); 44 | } 45 | }; 46 | 47 | return ( 48 | <> 49 | 58 | 59 | ); 60 | }; 61 | 62 | export default Inputs; 63 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | Smart Contract GUI 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/components/ContractExtracted.module.css: -------------------------------------------------------------------------------- 1 | .functionItems { 2 | /* background-color: aquamarine; */ 3 | /* display: flex; */ 4 | 5 | /* justify-content: space-evenly ; */ 6 | 7 | text-align: left; 8 | } 9 | .listGrid { 10 | display: grid; 11 | grid-template-columns: auto 15em 16em 4em 2em auto; 12 | } 13 | 14 | .functionLabel { 15 | margin-right: 1em; 16 | grid-column-start: 2; 17 | 18 | border: none; 19 | background-color: white; 20 | color: crimson; 21 | } 22 | 23 | .nonfunctionLabel { 24 | 25 | margin-right: 1em; 26 | grid-column-start: 2; 27 | border: none; 28 | background-color: white; 29 | color: rgb(5, 117, 65); 30 | } 31 | .inputWrapper { 32 | 33 | flex-direction: column; 34 | 35 | } 36 | .tooDeep { 37 | text-align: center; 38 | font-size: 0.7em; 39 | color: rgb(233, 136, 8); 40 | } 41 | 42 | .runBtnGreen { 43 | border: rgba(0, 0, 0, 0.068) 0.1em solid; 44 | background-color: rgb(255, 255, 255); 45 | border-radius: 0.5em; 46 | color: rgb(180, 180, 180); 47 | grid-column-start: 4; 48 | grid-column-end: 5; 49 | width: 3.5em; 50 | justify-self: end; 51 | height: auto; 52 | } 53 | .runBtnGreen:hover { 54 | border: rgb(255, 255, 255) 0.1em solid; 55 | background-color: rgb(46, 46, 46); 56 | cursor: pointer; 57 | color: white; 58 | } 59 | 60 | 61 | .functionCallBtn { 62 | border: rgb(1, 145, 89) 0.1em solid; 63 | background-color: rgb(255, 255, 255); 64 | border-radius: 0.5em; 65 | color: rgb(1, 145, 89); 66 | padding: 0.6em; 67 | width: 24em; 68 | } 69 | 70 | .functionCallBtn:hover { 71 | border: rgb(255, 255, 255) 0.1em solid; 72 | background-color: rgb(1, 145, 89); 73 | cursor: pointer; 74 | color: white; 75 | } 76 | 77 | .freeFunctionCallBtn { 78 | border: rgb(228, 3, 3) 0.1em solid; 79 | background-color: rgb(255, 255, 255); 80 | border-radius: 0.5em; 81 | color: rgb(228, 3, 3); 82 | padding: 0.6em; 83 | width: 24em; 84 | } 85 | 86 | .freeFunctionCallBtn:hover { 87 | border: rgb(255, 255, 255) 0.1em solid; 88 | background-color: rgb(228, 3, 3); 89 | cursor: pointer; 90 | color: white; 91 | } 92 | -------------------------------------------------------------------------------- /src/components/ContractExtracted.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import classes from './ContractExtracted.module.css'; 3 | import Inputs from './Inputs'; 4 | 5 | const ContractExtracted = (props) => { 6 | const [placeholderVal, setplaceholderVal] = useState(''); 7 | 8 | let fname = props.functionName; 9 | let receivedContractValues = ''; 10 | 11 | const functionBtnClicked = (args, fType) => { 12 | props.callFunctions(args, fType); 13 | }; 14 | 15 | const inputReceiver = (val) => { 16 | receivedContractValues = val; 17 | }; 18 | 19 | const contractTriggerHandler = () => { 20 | setplaceholderVal(''); 21 | functionBtnClicked(props.functionName, receivedContractValues); 22 | }; 23 | 24 | let editableFunction =

Unknow Type

; 25 | 26 | if (props.stateMutability === 'View') { 27 | editableFunction = ( 28 | 36 | ); 37 | if (props.inputs) { 38 | 39 | editableFunction = ( 40 | // green input 41 | 42 |
43 | {props.inputs.map((func) => ( 44 | 53 | ))} 54 |
55 | ); 56 | } 57 | } else if (props.type === 'Constructor') { 58 | return null; 59 | } else if (props.inputs) { 60 | editableFunction = ( 61 | //red input 62 | 63 |
64 | {props.inputs.map((func) => ( 65 | 74 | ))} 75 |
76 | ); 77 | } else { 78 | editableFunction = ( 79 | 87 | ); 88 | } 89 | 90 | return ( 91 |
92 | 112 |
113 | ); 114 | }; 115 | 116 | export default ContractExtracted; 117 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Preview](src/assets/screenshot.png) 2 | 3 | 4 | Working Demo: https://tron-gui.ibnz.dev/ 5 | 6 | This is a React, Tronweb, Tronlink experimental application to fetch Smart contract details and interact with smart contracts on TRON blockchain, Main Net, Nile Test Net, Shasta Test Net. 7 | 8 | ## Community coders, please commit 9 | 10 | Feel free to add extra functions or improvements, This helps me to familiarise myself with source control and open source project managing. By contributing you also help to build yet another open-source tool on TRON Network. 11 | 12 | ----- 13 | 14 | ## Experimental contracts for GUI testing: 15 | 16 | * SHASTA - `TWZYhE3WWAupJQ7KxKiwQDPkn1BGeM7PDJ` (Multiple Input Test, Set message, Read the message, Read Number, Change Data, Addition) 17 | * SHASTA - `TKWrw9VyRuvqg9n4oLdPMhbDLLgGutt1YV` (Array Demo for payable and nonpayable functions) 18 | * NILE - `TEjqDGMwDHqrXCzq7fWH8J63L1MWhc1msw` (NILE - Multiple Input Test, Set message, Read the message, Read Number, Change Data, Addition) 19 | * MAINNET - `TSYmsMxx2m9b5o8ZDLXT2fAGSXNY2RgDL6` (HummingDrop trc20 Token Airdrop) 20 | * MAINNET - `TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t` (USDT Token) 21 | 22 | 23 | 24 | 25 | ## Running instructions 26 | 27 | - Copy project to your directory ( git clone https://github.com/ibnzUK/smart-contract-gui ) 28 | - navigate to _smart-contract-gui_ project directory 29 | - make sure you have node.js installed on your machine 30 | - install project packages (npm install) 31 | - replace privateKey = 'xxx'; with your PK and store it in .env file 32 | - if you planning to use trongrid API add your keys to .env 33 | - start a project (npm run start) 34 | - make sure you have Tronlink wallet installed (https://www.tronlink.org/) 35 | - select network for your contract and enter smart contract address 36 | - if tronlink is not initialised, or you change wallet, refresh page or click on refresh button on the application right corner 37 | 38 | 39 | 40 | 41 | ## Changes in V 0.02 42 | 43 | - Integrated ability to refresh GUI (mainly after Tronlink address swap) 44 | - Added experimental Tronlink trigger option for cryptocurrency sending 45 | - Added ability to select test net Nile, Shasta or Main Tron network 46 | - UI Improvements 47 | 48 | ## Changes in V 0.03 49 | 50 | - Added ability to get Smart contract details 51 | - Added ability to fetch and render Smart contract functions 52 | - Added grid for Smart contract rendering 53 | - Optimised UI for a large list of functions 54 | 55 | ## Changes in V 0.04 56 | 57 | - Sorting functions into read-only, trigger and input 58 | - Implemented ability to check free contract functions 59 | 60 | ## Changes in V 0.05 61 | 62 | - Added ability to trigger functions without input with tronlink 63 | - Added input argument number counter 64 | - Sorting inputs by type 65 | 66 | 67 | ## Changes in V 0.06 68 | 69 | - Added placeholders for the user to identify type and name 70 | - Mapping inputs as new components 71 | - Fixed issue with a contract when not able to load after a quick swap 72 | - Ability to detect when contract does not exist on chain 73 | - Displaying transaction hash after function trigger 74 | 75 | ## Changes in V 0.07 76 | 77 | - Added ability to submit multiple fields at once 78 | - Implemented project support (donation) 79 | - Fixed styling 80 | - Optimised for mobile experience 81 | 82 | ## Changes in V 0.08 83 | 84 | - Added ability to view array elements 85 | - Added ability to submit arrays on payable functions 86 | - Implemented Return values for array triggering 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /src/components/Card.module.css: -------------------------------------------------------------------------------- 1 | .cardGrid { 2 | height: auto; 3 | display: grid; 4 | grid-template-columns: auto auto 40em auto auto; 5 | grid-template-rows: 10em auto auto 10em; 6 | } 7 | 8 | .first_border { 9 | 10 | grid-column: 2; 11 | grid-row: 1; 12 | width: 1em; 13 | } 14 | 15 | .last_border { 16 | grid-column: 4; 17 | grid-row: 1; 18 | width: 1em; 19 | } 20 | .card { 21 | background: rgba(255, 255, 255, 0.795); 22 | grid-column: 3; 23 | grid-row: 2; 24 | -webkit-box-shadow: rgba(0, 0, 0, 0.28) 0px 8px 28px; 25 | box-shadow: rgba(0, 0, 0, 0.28) 0px 8px 28px; 26 | border-radius: 1em; 27 | position: relative; 28 | width: auto; 29 | min-width: 630px; 30 | /* filter: blur(10px); */ 31 | } 32 | .underCard { 33 | border: solid rgba(255, 255, 255, 0) 1em; 34 | border-radius: 1em; 35 | backdrop-filter: blur(32px); 36 | height: auto; 37 | width: auto; 38 | grid-column-start: 3; 39 | grid-column-end: 4; 40 | 41 | grid-row-start: 2; 42 | grid-row-end: 3; 43 | } 44 | 45 | .cardFrame { 46 | /* background-color: rgb(84, 11, 253); */ 47 | outline: solid rgb(255, 255, 255) 1em; 48 | height: auto; 49 | width: auto; 50 | grid-column-start: 3; 51 | grid-column-end: 4; 52 | 53 | grid-row-start: 2; 54 | grid-row-end: 3; 55 | 56 | } 57 | 58 | 59 | 60 | .logo { 61 | height: auto; 62 | width: auto; 63 | grid-column-start: 2; 64 | grid-column-end: 5; 65 | 66 | grid-row-start: 1; 67 | grid-row-end: 5; 68 | 69 | } 70 | 71 | .header { 72 | background-color: rgba(255, 255, 255, 0); 73 | border-radius: 1em 1em 0 0; 74 | color: rgb(235, 11, 11); 75 | } 76 | 77 | .headerTop { 78 | 79 | display: flex; 80 | justify-content: space-between; 81 | } 82 | .headerTop p { 83 | 84 | text-align: center; 85 | color: #5c5c5c; 86 | } 87 | 88 | .myAddress { 89 | 90 | text-align: center; 91 | font-size: small; 92 | padding-bottom: 0.5em; 93 | color: rgba(119, 119, 119, 0.767); 94 | } 95 | 96 | .header h1 { 97 | 98 | text-align: center; 99 | font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 100 | font-weight: 400; 101 | font-size: 1.2em; 102 | } 103 | 104 | .content { 105 | 106 | background: rgba(235, 235, 235, 0.589); 107 | height: auto; 108 | text-align: center; 109 | padding-top: 4em; 110 | } 111 | 112 | .content p { 113 | 114 | color: green; 115 | font-size: 0.9em; 116 | } 117 | 118 | a { 119 | text-decoration: none; 120 | color: grey; 121 | } 122 | 123 | .contrctButton { 124 | padding: 1em; 125 | border-radius: 0.5em; 126 | background: rgb(49, 49, 49); 127 | color: white; 128 | font-size: 1em; 129 | } 130 | .contrctButtonDisabled { 131 | padding: 1em; 132 | border-radius: 0.5em; 133 | background: rgba(202, 202, 202, 0.795); 134 | color: white; 135 | font-size: 1em; 136 | border: none; 137 | } 138 | .contrctButtonDisabled:focus { 139 | outline: none; 140 | } 141 | 142 | .contrctButton:hover { 143 | background: #161616; /* Green */ 144 | color: rgb(255, 255, 255); 145 | cursor: pointer; 146 | } 147 | 148 | .contrctButton:focus { 149 | outline: none; 150 | } 151 | 152 | .inputField { 153 | background-color: rgba(255, 255, 255, 0.5); 154 | color: rgb(119, 119, 119); 155 | width: 65%; 156 | height: 3em; 157 | border-radius: 10px; 158 | border-width: 0px; 159 | font-size: 1.1em; 160 | text-align: center; 161 | } 162 | 163 | .inputField:focus { 164 | outline: none; 165 | } 166 | 167 | .foot { 168 | position: absolute; 169 | bottom: 0; 170 | width: 100%; 171 | background-color: rgba(255, 255, 255, 0); 172 | border-radius: 0em 0em 1em 1em ; 173 | } 174 | 175 | .foot h4 { 176 | text-align: center; 177 | font-size: 0.7em; 178 | font-family: sans-serif; 179 | color: rgb(145, 145, 145); 180 | } 181 | -------------------------------------------------------------------------------- /src/components/Card.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import classes from './Card.module.css'; 3 | import ContractExtracted from './ContractExtracted'; 4 | import NetworkStates from './NetworkStates'; 5 | import Refresh from './Refresh'; 6 | import TronlinkFunctions from './TronlinkFunctions'; 7 | import tronLogo from '../assets/tronLogo.svg'; 8 | 9 | const TronWeb = require('tronweb'); 10 | let privateKey = process.env.PK; 11 | const HttpProvider = TronWeb.providers.HttpProvider; 12 | let tronweb = window.tronWeb; 13 | // tronWeb.setHeader({ 'xxxxxxxxxxxxxxxxxxxxxxxx': 'your api key' }); 14 | 15 | //Smart Contract Examples 16 | // 17 | // * SHASTA - `TWZYhE3WWAupJQ7KxKiwQDPkn1BGeM7PDJ` (Multiple Input Test, Set message, Read the message, Read Number, Change Data, Addition) 18 | // * SHASTA - `TKWrw9VyRuvqg9n4oLdPMhbDLLgGutt1YV` (Array Demo for payable and nonpayable functions) 19 | // * NILE - `TEjqDGMwDHqrXCzq7fWH8J63L1MWhc1msw` (NILE - Multiple Input Test, Set message, Read the message, Read Number, Change Data, Addition) 20 | // * MAINNET - `TSYmsMxx2m9b5o8ZDLXT2fAGSXNY2RgDL6` (HummingDrop trc20 Token Airdrop) 21 | // * MAIN - `TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t` (USDT Token) 22 | 23 | const Card = () => { 24 | const [myAddress, setmyAddress] = useState(null); 25 | 26 | const [contrAdrress, setcontrAdrress] = useState(''); 27 | const [contractName, setcontractName] = useState('null'); 28 | const [fetchedFuncs, setFetchedFuncs] = useState([]); 29 | const [network, setNetwork] = useState('SHASTA'); 30 | //set nodes 31 | const [fullNode, setfullNode] = useState('https://api.shasta.trongrid.io'); 32 | const [solidityNode, setSolidityNode] = useState( 33 | 'https://api.shasta.trongrid.io' 34 | ); 35 | const [eventServer, setEventServer] = useState( 36 | 'https://api.shasta.trongrid.io' 37 | ); 38 | let tronWeb = new TronWeb(fullNode, solidityNode, eventServer, privateKey); 39 | 40 | const [contractValue, setContractValue] = useState('null'); 41 | const [contractExtracted, setContractExtracted] = useState([]); 42 | // const [tronLinkState, setTronLinkState] = useState({}); 43 | 44 | useEffect(() => { 45 | //connecting to tron blockchain 46 | const tronlinkEnabled = async () => { 47 | //checking if tronlink is enabled 48 | 49 | fetchAddressfromTronlink(); 50 | }; 51 | 52 | tronlinkEnabled(); 53 | }, []); 54 | 55 | const changeNetworkHandler = (net) => { 56 | if (net === 'SHASTA') { 57 | setfullNode('https://api.shasta.trongrid.io'); 58 | setSolidityNode('https://api.shasta.trongrid.io'); 59 | setEventServer('https://api.shasta.trongrid.io'); 60 | 61 | setNetwork('SHASTA'); 62 | } else if (net === 'MAIN') { 63 | setfullNode(new HttpProvider('https://api.trongrid.io')); 64 | setSolidityNode(new HttpProvider('https://api.trongrid.io')); 65 | setEventServer(new HttpProvider('https://api.trongrid.io')); 66 | 67 | setNetwork('MAIN'); 68 | } else if (net === 'NILE') { 69 | setfullNode('https://api.nileex.io'); 70 | setSolidityNode('https://api.nileex.io'); 71 | setEventServer('https://api.nileex.io'); 72 | setNetwork('NILE'); 73 | } 74 | }; 75 | 76 | const fetchAddressfromTronlink = async () => { 77 | try { 78 | setTimeout(() => { 79 | if (window.tronWeb) { 80 | setmyAddress(window.tronWeb.defaultAddress.base58); 81 | } else { 82 | setmyAddress(null); 83 | } 84 | }, 1000); 85 | } catch (error) { 86 | console.error('not able to fetch ', error); 87 | setmyAddress(error); 88 | } 89 | }; 90 | 91 | const getContractName = async () => { 92 | fetchAddressfromTronlink(); 93 | try { 94 | let contract = await tronWeb.trx.getContract(contrAdrress); 95 | 96 | let contractextracted = await tronWeb.contract().at(contrAdrress); 97 | let result = await contract.name; 98 | setcontractName(result); 99 | setContractExtracted(contractextracted.methodInstances); 100 | setFetchedFuncs(contract.abi.entrys); 101 | setContractValue(``); 102 | } catch (error) { 103 | console.error('trigger smart contract error', error); 104 | setcontractName(error); 105 | setFetchedFuncs(''); 106 | setContractExtracted(''); 107 | setContractValue(''); 108 | } 109 | }; 110 | 111 | const contractImputHandler = (event) => { 112 | event.preventDefault(); 113 | setcontrAdrress(event.target.value); 114 | }; 115 | 116 | const tronlinkTest = async () => { 117 | const tx = await tronweb.transactionBuilder.sendTrx( 118 | 'TBNZd3tqJuPYTtVGwDeR4wPNgBseX1QbAH', 119 | 100000000, 120 | myAddress 121 | ); 122 | const signedTx = await tronweb.trx.sign(tx); 123 | const broastTx = await tronweb.trx.sendRawTransaction(signedTx); 124 | console.log(broastTx); 125 | }; 126 | 127 | const callFunctions = async (args, type) => { 128 | let contract = await tronWeb.contract().at(contrAdrress); 129 | tronWeb.setAddress(myAddress); 130 | 131 | if (type[0].ftype === 'View') { 132 | let currentValue = await contract[args](type[0].value).call(); 133 | setContractValue(currentValue.toString()); 134 | } else if (type === 'Free') { 135 | let currentValue = await contract[args].call().call(); 136 | setContractValue(currentValue.toString()); 137 | } else if (type === 'Nonpayable') { 138 | let contract = await window.tronWeb.contract().at(contrAdrress); 139 | tronWeb.setAddress(myAddress); 140 | 141 | let transaction = await contract[args].call().send({ 142 | feeLimit: 1000000, 143 | }); 144 | 145 | setContractValue(`Success: ${transaction}`); 146 | } else { 147 | const contractFunction = contract.methodInstances[args].functionSelector; 148 | 149 | const options = { 150 | feeLimit: 100000000, 151 | callValue: 0, 152 | }; 153 | 154 | // tronlink building transaction 155 | const transaction = 156 | await window.tronWeb.transactionBuilder.triggerSmartContract( 157 | contrAdrress, 158 | contractFunction, 159 | options, 160 | type, 161 | myAddress 162 | ); 163 | 164 | //tronlink signing transaction 165 | const signedTx = await tronweb.trx.sign(transaction.transaction); 166 | //tronlink broadcasting transaction 167 | const broastTx = await tronweb.trx.sendRawTransaction(signedTx); 168 | 169 | setContractValue(`Success: ${broastTx.txid}`); 170 | } 171 | }; 172 | 173 | return ( 174 |
175 |
176 |
177 |
178 |
179 | tron logo 180 |
181 |
182 |
183 |
184 | 188 | 189 |
190 |

SMART CONTRACT GUI

191 |
192 | {myAddress ? ( 193 |

194 | Network ({network}): {myAddress} 195 |

196 | ) : ( 197 |

198 | 203 | TRONLINK NOT DETECTED 204 | 205 |

206 | )} 207 | 208 |
209 |
210 | {contractValue === 'null' ?

:

{contractValue}

} 211 |
212 | {contractName === 'null' ? ( 213 |

Enter smart contract address

214 | ) : ( 215 |

Contract name: {contractName}

216 | )} 217 | 218 |
219 | {fetchedFuncs 220 | ? fetchedFuncs.map((func) => ( 221 | 231 | )) 232 | : null} 233 |
234 | 235 | 240 |
241 |

242 |
243 | 244 | 247 | 248 | 249 | 250 |
251 |
252 |

V 0.08 / 2021 © IBNZ DEVELOPERS

253 |
254 |
255 |
256 |
257 | ); 258 | }; 259 | 260 | export default Card; 261 | --------------------------------------------------------------------------------