Skip to content

Commit 10d5bcd

Browse files
committed
Initial commit
0 parents  commit 10d5bcd

File tree

11 files changed

+2697
-0
lines changed

11 files changed

+2697
-0
lines changed

.gitignore

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
### Node ###
2+
# Logs
3+
logs
4+
*.log
5+
npm-debug.log*
6+
yarn-debug.log*
7+
yarn-error.log*
8+
lerna-debug.log*
9+
10+
# Diagnostic reports (https://nodejs.org/api/report.html)
11+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
12+
13+
# Runtime data
14+
pids
15+
*.pid
16+
*.seed
17+
*.pid.lock
18+
19+
# Directory for instrumented libs generated by jscoverage/JSCover
20+
lib-cov
21+
22+
# Coverage directory used by tools like istanbul
23+
coverage
24+
*.lcov
25+
26+
# nyc test coverage
27+
.nyc_output
28+
29+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
30+
.grunt
31+
32+
# Bower dependency directory (https://bower.io/)
33+
bower_components
34+
35+
# node-waf configuration
36+
.lock-wscript
37+
38+
# Compiled binary addons (https://nodejs.org/api/addons.html)
39+
build/Release
40+
41+
# Dependency directories
42+
node_modules/
43+
jspm_packages/
44+
45+
# TypeScript v1 declaration files
46+
typings/
47+
48+
# TypeScript cache
49+
*.tsbuildinfo
50+
51+
# Optional npm cache directory
52+
.npm
53+
54+
# Optional eslint cache
55+
.eslintcache
56+
57+
# Microbundle cache
58+
.rpt2_cache/
59+
.rts2_cache_cjs/
60+
.rts2_cache_es/
61+
.rts2_cache_umd/
62+
63+
# Optional REPL history
64+
.node_repl_history
65+
66+
# Output of 'npm pack'
67+
*.tgz
68+
69+
# Yarn Integrity file
70+
.yarn-integrity
71+
72+
# dotenv environment variables file
73+
.env
74+
.env.test
75+
76+
# parcel-bundler cache (https://parceljs.org/)
77+
.cache
78+
79+
# Next.js build output
80+
.next
81+
82+
# Nuxt.js build / generate output
83+
.nuxt
84+
dist
85+
86+
# Gatsby files
87+
.cache/
88+
# Comment in the public line in if your project uses Gatsby and not Next.js
89+
# https://nextjs.org/blog/next-9-1#public-directory-support
90+
# public
91+
92+
# vuepress build output
93+
.vuepress/dist
94+
95+
# Serverless directories
96+
.serverless/
97+
98+
# FuseBox cache
99+
.fusebox/
100+
101+
# DynamoDB Local files
102+
.dynamodb/
103+
104+
# TernJS port file
105+
.tern-port
106+
107+
# Stores VSCode versions used for testing VSCode extensions
108+
.vscode-test
109+
110+
### OSX ###
111+
# General
112+
.DS_Store
113+
.AppleDouble
114+
.LSOverride
115+
116+
# Icon must end with two \r
117+
Icon
118+
119+
# Thumbnails
120+
._*
121+
122+
# Files that might appear in the root of a volume
123+
.DocumentRevisions-V100
124+
.fseventsd
125+
.Spotlight-V100
126+
.TemporaryItems
127+
.Trashes
128+
.VolumeIcon.icns
129+
.com.apple.timemachine.donotpresent
130+
131+
# Directories potentially created on remote AFP share
132+
.AppleDB
133+
.AppleDesktop
134+
Network Trash Folder
135+
Temporary Items
136+
.apdisk
137+
138+
### Serverless ###
139+
# Ignore build directory
140+
.serverless

.nvmrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
12.13.0

README.md

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# serverless-ethers
2+
3+
## Table of Contents
4+
5+
| | Description | Stack |
6+
| ----------------------------------- | ------------------------------------------- | --------------------- |
7+
| [`contracts`](contracts) | 🖼 Smart contract ABIs | `json`, `ethereum` |
8+
| [`functions`](functions) | 🚀 Lambda functions | `node`, `js` |
9+
10+
## Prerequisites
11+
12+
Install the [Serverless Framework CLI](https://www.serverless.com/framework/docs/getting-started/).
13+
14+
## Getting Started
15+
16+
```bash
17+
git clone [email protected]:yosriady/serverless-ethers.git
18+
cd serverless-ethers
19+
nvm use
20+
npm install
21+
```
22+
23+
### Set your environment variables
24+
25+
You can find and update the function's configuration in [`serverless.yml`](https://github.com/yosriady/serverless-ethers/blob/master/serverless.yml):
26+
27+
```yml
28+
service: serverless-ethers
29+
provider:
30+
name: aws
31+
runtime: nodejs12.x
32+
region: ap-southeast-1
33+
timeout: 30
34+
environment:
35+
DEFAULT_GAS_PRICE: 60000000000
36+
MNEMONIC: ...
37+
```
38+
39+
This example uses the following environment variables:
40+
41+
- `DEFAULT_GAS_PRICE`: Default gas price used when making write transactions.
42+
- `MNEMONIC`: 12-word mnemonic used to derive an Ethereum address, make sure it's funded with Ether if you intend to write data to Ethereum!
43+
- `SLACK_HOOK_URL`: The example sends messages to Slack using [Incoming Webhooks](https://api.slack.com/messaging/webhooks). You can get this URL from your Slack dashboard. (Optional)
44+
45+
> You can change your deployed function's environment variables on the fly from the AWS Lambda console.
46+
47+
### Triggering the function locally
48+
49+
```bash
50+
serverless invoke local --function exec
51+
```
52+
53+
This will execute the smart contract function from your local machine.
54+
Great for debugging and testing.
55+
56+
### Deploying to AWS
57+
58+
```bash
59+
serverless deploy
60+
```
61+
62+
## Thanks
63+
64+
**serverless-ethers** 💌 2020+, Yos Riady. Released under the [MIT] License.<br>
65+
Authored and maintained by Yos Riady with help from contributors ([list][contributors]).
66+
67+
> [yos.io](http://yos.io) &nbsp;&middot;&nbsp;
68+
> GitHub [@yosriady](https://github.com/yosriady)
69+
70+
[MIT]: http://mit-license.org/
71+
[contributors]: http://github.com/yosriady/serverless-ethers/contributors

contracts/abis.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const DummyStorage = require("./abis/DummyStorage.json");
2+
3+
const abis = {
4+
DummyStorage,
5+
};
6+
7+
module.exports = abis;

contracts/abis/DummyStorage.json

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
[{
2+
"anonymous": false,
3+
"inputs": [{
4+
"indexed": true,
5+
"internalType": "address",
6+
"name": "source",
7+
"type": "address"
8+
}, {
9+
"indexed": false,
10+
"internalType": "uint256",
11+
"name": "value",
12+
"type": "uint256"
13+
}],
14+
"name": "Write",
15+
"type": "event"
16+
}, {
17+
"inputs": [],
18+
"name": "get",
19+
"outputs": [{
20+
"internalType": "uint256",
21+
"name": "",
22+
"type": "uint256"
23+
}],
24+
"stateMutability": "view",
25+
"type": "function"
26+
}, {
27+
"inputs": [{
28+
"internalType": "uint256",
29+
"name": "value",
30+
"type": "uint256"
31+
}],
32+
"name": "put",
33+
"outputs": [],
34+
"stateMutability": "nonpayable",
35+
"type": "function"
36+
}]

contracts/addresses.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const addresses = {
2+
DummyStorage: "0xfb01bf6abde080a278a7bbc62f3ba568380eafed",
3+
};
4+
5+
module.exports = addresses;

contracts/index.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const abis = require("./abis");
2+
const addresses = require("./addresses");
3+
4+
module.exports = {
5+
abis,
6+
addresses,
7+
}

functions/exec.js

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
const axios = require('axios');
2+
const ethers = require('ethers');
3+
const { abis, addresses } = require('../contracts');
4+
5+
exports.handler = async function() {
6+
console.log('Starting...');
7+
// Load Contract ABIs
8+
const DummyStorageABI = abis.DummyStorage;
9+
const DummyStorageAddress = addresses.DummyStorage;
10+
console.log('Contract ABIs loaded');
11+
12+
// Initialize Ethers wallet
13+
const provider = new ethers.getDefaultProvider(parseInt(process.env.CHAIN_ID))
14+
let wallet = ethers.Wallet.fromMnemonic(process.env.MNEMONIC)
15+
wallet = wallet.connect(provider)
16+
console.log('Ethers wallet loaded');
17+
18+
// Load contract
19+
const contract = new ethers.Contract(
20+
DummyStorageAddress,
21+
DummyStorageABI,
22+
wallet,
23+
)
24+
console.log('Contract loaded');
25+
26+
console.log('Sending transaction...');
27+
try {
28+
// Specify custom tx overrides, such as gas price https://docs.ethers.io/ethers.js/v5-beta/api-contract.html#overrides
29+
const overrides = { gasPrice: process.env.DEFAULT_GAS_PRICE };
30+
31+
// Call smart contract function `put(uint)`
32+
const RANDOM_INTEGER = Math.floor(Math.random() * 100); // returns a random integer from 0 to 99
33+
const tx = await contract.put(RANDOM_INTEGER, overrides)
34+
35+
const successMessage = `:white_check_mark: Transaction sent https://ropsten.etherscan.io/tx/${tx.hash}`;
36+
console.log(successMessage)
37+
await postToSlack(successMessage);
38+
} catch (err) {
39+
const errorMessage = `:warning: Transaction failed: ${err.message}`;
40+
console.error(errorMessage)
41+
await postToSlack(errorMessage);
42+
return err;
43+
}
44+
45+
console.log('Completed');
46+
return true;
47+
}
48+
49+
function postToSlack(text) {
50+
const payload = JSON.stringify({
51+
text,
52+
});
53+
return axios.post(process.env.SLACK_HOOK_URL, payload)
54+
}

0 commit comments

Comments
 (0)