This is a read-only snapshot of the ComputerCraft forums,
taken in April 2020.
Computercraft Virtual Currency
Started by pauliuskas05, 05 July 2014 - 01:42 PMPosted 05 July 2014 - 03:42 PM
Hi, I am a noob on ComputerCraft. I really want to make a Virtual Currency on my server. So that it use floppy disks as Credit Cards, but only keep account name in them. Everything else (password, balance) would be on a server computer.
Posted 05 July 2014 - 05:45 PM
Well, if your new to ComputerCraft and Lua I would NOT recommend a virtual currency system as your first project. First, go read some tutorials on Lua, and some on the ComputerCraft apis. Then, you should make some simple programs and learn rednet. But, if you think your ready then read on:
First, you'll want to have some encryption system. I recommend using my [topic='19328']Encryption Api[/topic] for the key exchange and [topic='42']StrUtils[/topic] for the actual encryption.
Next, you want to set up a packet protocol, this involves parsing rednet messages and doing the corresponding action.
Finally, you want to make sure you hash your passwords when sending them to the server for extra security.
That's all there is to it, kinda complicated, but kinda simple with the right apis. If you need anymore help, I check the forums twice a day and am often on the irc, just shout my name!
PS: I don't recommend using disks for credit cards as they can easily be cloned.
First, you'll want to have some encryption system. I recommend using my [topic='19328']Encryption Api[/topic] for the key exchange and [topic='42']StrUtils[/topic] for the actual encryption.
Next, you want to set up a packet protocol, this involves parsing rednet messages and doing the corresponding action.
Finally, you want to make sure you hash your passwords when sending them to the server for extra security.
That's all there is to it, kinda complicated, but kinda simple with the right apis. If you need anymore help, I check the forums twice a day and am often on the irc, just shout my name!
PS: I don't recommend using disks for credit cards as they can easily be cloned.
Posted 05 July 2014 - 05:59 PM
PS: I don't recommend using disks for credit cards as they can easily be cloned.
Why not ? On them there is going to be only account name that can only be accessed with password.
Posted 06 July 2014 - 01:16 AM
Oh, ok. I thought you were gonna store the password on the card as well.PS: I don't recommend using disks for credit cards as they can easily be cloned.
Why not ? On them there is going to be only account name that can only be accessed with password.
Posted 06 July 2014 - 01:18 AM
Well if he was going to then he could hash them :P/>Oh, ok. I thought you were gonna store the password on the card as well.PS: I don't recommend using disks for credit cards as they can easily be cloned.
Why not ? On them there is going to be only account name that can only be accessed with password.
Posted 06 July 2014 - 02:19 AM
It's easy enough to copy a disk's contents. It's nearly impossible to clone a disk's ID number. There doesn't need to be anything on a disk at all if you purely want to use it for identification - in fact, done properly, use of disks would also negate any need to even ask for a password… So long as the disks themselves aren't stealable…
Posted 06 July 2014 - 02:52 AM
But then someone could just copy the hashWell if he was going to then he could hash them :P/>Oh, ok. I thought you were gonna store the password on the card as well.PS: I don't recommend using disks for credit cards as they can easily be cloned.
Why not ? On them there is going to be only account name that can only be accessed with password.
Hm, never thought of that, how do you read the disk's id from the computer?It's easy enough to copy a disk's contents. It's nearly impossible to clone a disk's ID number. There doesn't need to be anything on a disk at all if you purely want to use it for identification - in fact, done properly, use of disks would also negate any need to even ask for a password… So long as the disks themselves aren't stealable…
Posted 06 July 2014 - 03:30 AM
Well if you do it right, it doesn't matter if people can see the hash, 'cause they need to enter the password, not the hashed password.
Take a look into the Disk API for how to get info about disks.
Take a look into the Disk API for how to get info about disks.
Posted 07 July 2014 - 04:30 PM
This (in my opinion at least) is a great idea. A currency that can be used in computercraft servers! Finally we will have something else to try and hack other than computers! Just kiddin (not really) but I think it is a great idea!
Posted 07 July 2014 - 09:50 PM
I writed some code, but it doesn't seems to work. When I will get home i will post it…
Edited on 07 July 2014 - 07:53 PM
Posted 08 July 2014 - 10:07 AM
I writed some code, but it doesn't seems to work. When I will get home i will post it…
I worked on something aswell but it also didn't seem to work. Well…I will check it out today after all I wrote the program in 2am yesterday so I couldn't make out any mistakes in the code
Posted 08 July 2014 - 10:25 AM
The problem with this is that there can be a big freakin' problem. What will happen if someone kills you and steals your "credit card"? Well one possibility would be to make checks every now and then. So for example every fifth purchase you ask the user to input his code or else they block the card. Also checks can be make where the server has a countdown. Once the countdown is over for the next purchase the user needs his code. There is a problem with both…First with the first one the thief would go to a store and buy a lot of things all in once and it would be on you to pay them! The second idea also has a problem because the thief can buy anything he wants before the check is up. But supposing you are not in a hardcore server (so you don't get kicked when you die) the user of the card can go to the bank and say that his card was stolen so they can instantly block it the point is that the thief is still given some time to buy whatever he wants. So…I guess that we will have to find a way of tightening security
Posted 09 July 2014 - 10:55 AM
ATM Code:
Server Code:
On ATM I get Error
Help me !
EDIT:
BTW I am using "Config API' by ben657
local modem_side = "back"
local server = 6
local d_side = "bottom"
local pin_check = nil
local exists = nil
function cls()
term.clear()
term.setCursorPos(1,1)
print("BANK")
term.setCursorPos(1,2)
end
function dej()
disk.eject(d_side)
end
rednet.open(modem_side)
cls()
print(" Please insert your Credit Card")
local event, isDisk = os.pullEvent("disk")
if fs.exists("disk/bank") then
local ccid = disk.getID(d_side)
rednet.send(server, ccid)
senderId, exists, distance= rednet.receive()
if exists == "yes" then
cls()
write(" PIN: ")
local pin = read("*")
rednet.send(server, pin)
senderId, pin_check, distance = rednet.receive()
if pin_check == "good" then
pin = nil
pin_check = nil
senderId, money, distance = rednet.receive()
print("You have: "..money)
elseif pin_check == "bad" then
cls()
print("Wrong PIN !")
end
elseif exists == "no" then
cls()
print(" Account doesn't exists")
end
else
cls()
print(" This is not a credit card")
dej()
sleep(1.5)
os.shutdown()
end
Server Code:
term.clear()
term.setCursorPos(1,1)
local modem_side = "top"
local srv_id = os.getComputerID()
print("Running BANK server on "..srv_id)
rednet.open(modem_side)
while true do
senderId, id, distance = rednet.receive()
if fs.exists("acc/"..id) then
rednet.send(senderId, "yes")
config.load("acc",id)
local real_pass = config.readVal("pass")
senderId, pass, distance = rednet.receive()
if pass == real_pass then
rednet.send(senderId, "good")
local money = config.readVal("money")
rednet.send(senderId, money)
break
elseif pass ~= real_pass then
rednet.send(senderId, "bad")
break
end
else
rednet.send(senderId, "no")
break
end
end
On ATM I get Error
startup:23: attempt to call nil
Help me !
EDIT:
BTW I am using "Config API' by ben657
Edited on 09 July 2014 - 08:56 PM
Posted 09 July 2014 - 01:12 PM
ATM Code:local modem_side = "back" local server = 6 local d_side = "bottom" local pin_check = nil local exists = nil function cls() term.clear() term.setCursorPos(1,1) print("BANK") term.setCursorPos(1,2) end function dej() disk.eject(d_side) end rednet.open(modem_side) cls() print(" Please insert your Credit Card") local event, isDisk = os.pullEvent("disk") if fs.exists("disk/bank") then local ccid = disk.getID(d_side) rednet.send(server, ccid) senderId, exists, distance= rednet.receive() if exists == "yes" then cls() write(" PIN: ") local pin = read("*") rednet.send(server, pin) senderId, pin_check, distance = rednet.receive() if pin_check == "good" then pin = nil pin_check = nil senderId, money, distance = rednet.receive() print("You have: "..money) elseif pin_check == "bad" then cls() print("Wrong PIN !") end elseif exists == "no" then cls() print(" Account doesn't exists") end else cls() print(" This is not a credit card") dej() sleep(1.5) os.shutdown() end
Server Code:term.clear() term.setCursorPos(1,1) local modem_side = "top" local srv_id = os.getComputerID() print("Running BANK server on "..srv_id) rednet.open(modem_side) while true do senderId, id, distance = rednet.receive() if fs.exists("acc/"..id) then rednet.send(senderId, "yes") config.load("acc",id) local real_pass = config.readVal("pass") senderId, pass, distance = rednet.receive() if pass == real_pass then rednet.send(senderId, "good") local money = config.readVal("money") rednet.send(senderId, money) break elseif pass ~= real_pass then rednet.send(senderId, "bad") break end else rednet.send(senderId, "no") break end end
On ATM I get Errorstartup:23: attempt to call nil
Help me !
Your code is…HUGE (no offence). Btw I am really close to completing it and it reaquires a lot less code(well I did it slightly differently but I also get nearly the same erroe :(/>
Posted 11 July 2014 - 08:34 PM
Anybody ? I have no idea what causes this error…
Posted 11 July 2014 - 08:46 PM
Which of your 2 programs errors? The ATM or the server? Also, read this for common errors and how to fix them: http://www.computercraft.info/forums2/index.php?/topic/14531-read-this-post-before-asking-questions/#common_errors
Edited on 11 July 2014 - 06:48 PM
Posted 11 July 2014 - 10:55 PM
All right. Here you go! Got it working:
Bank Server Code:
And here is the code for the counter of the store:
This is how it works:
1)The computer in the store sends a mesage to the bank server containing the cards ID.
2)The server checks in its table to see if the first number of the tables inside the table match the ID
3)If they do the server sends a message to the computer telling it to send it the amount
4)The computer checks the amount and sees if the second number inside the table the ID was found is bigger or equal to the amount
5)If it is it subtracts the amount from the money in the bank and sends a message to the computer saying that the transaction has been completed.
I will do ATMs tommorow (its already 1am :D/> ) and post the code
Bank Server Code:
rednet.open("right")
cards = {{1, 1000}, {2, 550}}
while true do
senderId, ID = rednet.receive("id")
for i = 1, #cards do
if cards[i][1] == ID then
rednet.send(22, "yes", "answer")
senderId, amount = rednet.receive("pay")
if cards[i][2] >= amount then
rednet.send(22, "done", "transaction")
cards[i][2] = cards[i][2] - amount
else
rednet.send(22, "nope", "transaction")
end
else
rednet.send(22, "noCustomer", "transaction")
end
end
end
And here is the code for the counter of the store:
diskID = disk.getID("bottom")
amount = 100
rednet.open("right")
rednet.send(23, diskID, "id")
repeat
senderId, message = rednet.receive("answer")
until senderId == 23
if message == "yes" then
rednet.send(23, amount, "pay")
senderId, message = rednet.receive("transaction")
if senderId == 23 and message == "done" then
print("Transaction Complete!")
elseif senderId == 23 and message == "nope" then
print("Transaction Failed: Not enough money")
else
print("No such customer")
end
end
This is how it works:
1)The computer in the store sends a mesage to the bank server containing the cards ID.
2)The server checks in its table to see if the first number of the tables inside the table match the ID
3)If they do the server sends a message to the computer telling it to send it the amount
4)The computer checks the amount and sees if the second number inside the table the ID was found is bigger or equal to the amount
5)If it is it subtracts the amount from the money in the bank and sends a message to the computer saying that the transaction has been completed.
I will do ATMs tommorow (its already 1am :D/> ) and post the code
Posted 11 July 2014 - 11:03 PM
I will do ATMs tommorow (its already 1am :D/> ) and post the code
Actually I won't because ATMs dispence virtual currency as real-life money. I don't see the point in making such a thing (I mean its more about redstone thatn computers). Plus why use solid money when you can access your bank account from anywhere? Not that a hacker can't steal your money this way but if you carry real money the thief that will kill you can steal it and you can't retreave it but with this you can go to the bank and report you stolen card and they will stop all transactions happening using that specific card. Plus while an ATM dispences money a guy sitting close can easily pick up some. Both ways have an enemy. So its your call which you will use. If you want I will make an ATM just ask.
Posted 15 July 2014 - 09:40 AM
I will do ATMs tommorow (its already 1am :D/>/>/> ) and post the code
Actually I won't because ATMs dispence virtual currency as real-life money. I don't see the point in making such a thing (I mean its more about redstone thatn computers). Plus why use solid money when you can access your bank account from anywhere? Not that a hacker can't steal your money this way but if you carry real money the thief that will kill you can steal it and you can't retreave it but with this you can go to the bank and report you stolen card and they will stop all transactions happening using that specific card. Plus while an ATM dispences money a guy sitting close can easily pick up some. Both ways have an enemy. So its your call which you will use. If you want I will make an ATM just ask.
It's only VIRTAUL, so there is no cash to give out.
EDIT:
BTW I am on vacation. So I won't always be online.
Edited on 15 July 2014 - 07:44 AM
Posted 15 July 2014 - 11:09 AM
I will do ATMs tommorow (its already 1am :D/>/>/> ) and post the code
Actually I won't because ATMs dispence virtual currency as real-life money. I don't see the point in making such a thing (I mean its more about redstone thatn computers). Plus why use solid money when you can access your bank account from anywhere? Not that a hacker can't steal your money this way but if you carry real money the thief that will kill you can steal it and you can't retreave it but with this you can go to the bank and report you stolen card and they will stop all transactions happening using that specific card. Plus while an ATM dispences money a guy sitting close can easily pick up some. Both ways have an enemy. So its your call which you will use. If you want I will make an ATM just ask.
It's only VIRTAUL, so there is no cash to give out.
EDIT:
BTW I am on vacation. So I won't always be online.
Yes but it would be nice wouldn't it? and btw hackers can do some cool tricks to steal you money from the bank. As I said you are not safe in any of the two ways so its your call. I guess having both would be the best option :)/>
Posted 15 July 2014 - 03:11 PM
By the way, using a PIM to stand on (OpenPeripherals) when you insert your credit card would allow you to verify the user with PIM.inventoryName() as well as allow you to interact directly with the players inventory, allowing him to withdraw "cash" or deposit into his account without the risk entailed with dispensers
Posted 16 July 2014 - 09:42 PM
Bank Server Code:rednet.open("right") cards = {{1, 1000}, {2, 550}} while true do senderId, ID = rednet.receive("id") for i = 1, #cards do if cards[i][1] == ID then rednet.send(22, "yes", "answer") senderId, amount = rednet.receive("pay") if cards[i][2] >= amount then rednet.send(22, "done", "transaction") cards[i][2] = cards[i][2] - amount else rednet.send(22, "nope", "transaction") end else rednet.send(22, "noCustomer", "transaction") end end end
Well, this code is very good, but is there a way to load bank accounts from file ?
Because I need a way to edit and create accounts easily. With program or just using edit…
Edited on 17 July 2014 - 08:05 AM
Posted 18 July 2014 - 08:35 AM
But this isn't secure. Because there is no PIN, so anyone who has your card can access it. :(/>Bank Server Code:rednet.open("right") cards = {{1, 1000}, {2, 550}} while true do senderId, ID = rednet.receive("id") for i = 1, #cards do if cards[i][1] == ID then rednet.send(22, "yes", "answer") senderId, amount = rednet.receive("pay") if cards[i][2] >= amount then rednet.send(22, "done", "transaction") cards[i][2] = cards[i][2] - amount else rednet.send(22, "nope", "transaction") end else rednet.send(22, "noCustomer", "transaction") end end end
And here is the code for the counter of the store:diskID = disk.getID("bottom") amount = 100 rednet.open("right") rednet.send(23, diskID, "id") repeat senderId, message = rednet.receive("answer") until senderId == 23 if message == "yes" then rednet.send(23, amount, "pay") senderId, message = rednet.receive("transaction") if senderId == 23 and message == "done" then print("Transaction Complete!") elseif senderId == 23 and message == "nope" then print("Transaction Failed: Not enough money") else print("No such customer") end end
This is how it works:
1)The computer in the store sends a mesage to the bank server containing the cards ID.
2)The server checks in its table to see if the first number of the tables inside the table match the ID
3)If they do the server sends a message to the computer telling it to send it the amount
4)The computer checks the amount and sees if the second number inside the table the ID was found is bigger or equal to the amount
5)If it is it subtracts the amount from the money in the bank and sends a message to the computer saying that the transaction has been completed.
Posted 27 July 2014 - 08:09 PM
But this isn't secure. Because there is no PIN, so anyone who has your card can access it. :(/>Bank Server Code:rednet.open("right") cards = {{1, 1000}, {2, 550}} while true do senderId, ID = rednet.receive("id") for i = 1, #cards do if cards[i][1] == ID then rednet.send(22, "yes", "answer") senderId, amount = rednet.receive("pay") if cards[i][2] >= amount then rednet.send(22, "done", "transaction") cards[i][2] = cards[i][2] - amount else rednet.send(22, "nope", "transaction") end else rednet.send(22, "noCustomer", "transaction") end end end
And here is the code for the counter of the store:diskID = disk.getID("bottom") amount = 100 rednet.open("right") rednet.send(23, diskID, "id") repeat senderId, message = rednet.receive("answer") until senderId == 23 if message == "yes" then rednet.send(23, amount, "pay") senderId, message = rednet.receive("transaction") if senderId == 23 and message == "done" then print("Transaction Complete!") elseif senderId == 23 and message == "nope" then print("Transaction Failed: Not enough money") else print("No such customer") end end
This is how it works:
1)The computer in the store sends a mesage to the bank server containing the cards ID.
2)The server checks in its table to see if the first number of the tables inside the table match the ID
3)If they do the server sends a message to the computer telling it to send it the amount
4)The computer checks the amount and sees if the second number inside the table the ID was found is bigger or equal to the amount
5)If it is it subtracts the amount from the money in the bank and sends a message to the computer saying that the transaction has been completed.
Yea I know but really I mean why can't we give those hackers something to do?
Posted 28 July 2014 - 08:43 PM
I could make PINs myself, but I don't know how to use tables and assign them to a Credit Card(ID)…But this isn't secure. Because there is no PIN, so anyone who has your card can access it. :(/>/>Bank Server Code:rednet.open("right") cards = {{1, 1000}, {2, 550}} while true do senderId, ID = rednet.receive("id") for i = 1, #cards do if cards[i][1] == ID then rednet.send(22, "yes", "answer") senderId, amount = rednet.receive("pay") if cards[i][2] >= amount then rednet.send(22, "done", "transaction") cards[i][2] = cards[i][2] - amount else rednet.send(22, "nope", "transaction") end else rednet.send(22, "noCustomer", "transaction") end end end
And here is the code for the counter of the store:diskID = disk.getID("bottom") amount = 100 rednet.open("right") rednet.send(23, diskID, "id") repeat senderId, message = rednet.receive("answer") until senderId == 23 if message == "yes" then rednet.send(23, amount, "pay") senderId, message = rednet.receive("transaction") if senderId == 23 and message == "done" then print("Transaction Complete!") elseif senderId == 23 and message == "nope" then print("Transaction Failed: Not enough money") else print("No such customer") end end
This is how it works:
1)The computer in the store sends a mesage to the bank server containing the cards ID.
2)The server checks in its table to see if the first number of the tables inside the table match the ID
3)If they do the server sends a message to the computer telling it to send it the amount
4)The computer checks the amount and sees if the second number inside the table the ID was found is bigger or equal to the amount
5)If it is it subtracts the amount from the money in the bank and sends a message to the computer saying that the transaction has been completed.
Yea I know but really I mean why can't we give those hackers something to do?
Posted 30 July 2014 - 02:33 PM
I could make PINs myself, but I don't know how to use tables and assign them to a Credit Card(ID)…But this isn't secure. Because there is no PIN, so anyone who has your card can access it. :(/>/>Bank Server Code:rednet.open("right") cards = {{1, 1000}, {2, 550}} while true do senderId, ID = rednet.receive("id") for i = 1, #cards do if cards[i][1] == ID then rednet.send(22, "yes", "answer") senderId, amount = rednet.receive("pay") if cards[i][2] >= amount then rednet.send(22, "done", "transaction") cards[i][2] = cards[i][2] - amount else rednet.send(22, "nope", "transaction") end else rednet.send(22, "noCustomer", "transaction") end end end
And here is the code for the counter of the store:diskID = disk.getID("bottom") amount = 100 rednet.open("right") rednet.send(23, diskID, "id") repeat senderId, message = rednet.receive("answer") until senderId == 23 if message == "yes" then rednet.send(23, amount, "pay") senderId, message = rednet.receive("transaction") if senderId == 23 and message == "done" then print("Transaction Complete!") elseif senderId == 23 and message == "nope" then print("Transaction Failed: Not enough money") else print("No such customer") end end
This is how it works:
1)The computer in the store sends a mesage to the bank server containing the cards ID.
2)The server checks in its table to see if the first number of the tables inside the table match the ID
3)If they do the server sends a message to the computer telling it to send it the amount
4)The computer checks the amount and sees if the second number inside the table the ID was found is bigger or equal to the amount
5)If it is it subtracts the amount from the money in the bank and sends a message to the computer saying that the transaction has been completed.
Yea I know but really I mean why can't we give those hackers something to do?
PIN isn't hard to make just go to the server and at the table add for each an extra string (PIN) inside each table (eg {1, 1000, "1234"}). The you need to modify the counter code to take a string and send it along with the rest of thi information to the bank server (make sure the bank server receives it). Finally and an if statement in the bank server before the if cards[2] >= amount etc etc stating the following:
if cards[i][3] == <variable in which the ping from the counter is> then
<if cards[i][2] >= amount in here>
else
rednet.send(id, "nope") <you may need to modify this>
end
Posted 30 July 2014 - 06:25 PM
Thanks! I will test it later.PIN isn't hard to make just go to the server and at the table add for each an extra string (PIN) inside each table (eg {1, 1000, "1234"}). The you need to modify the counter code to take a string and send it along with the rest of thi information to the bank server (make sure the bank server receives it). Finally and an if statement in the bank server before the if cards[2] >= amount etc etc stating the following:if cards[i][3] == <variable in which the ping from the counter is> then <if cards[i][2] >= amount in here> else rednet.send(id, "nope") <you may need to modify this> end
Posted 02 August 2014 - 09:40 PM
The reason I didn't put a PIN in the original code is because a PIN need to be added by the user as a result it takes a bit of time to do so. So with that in mind if a server hosts multiple stores for example that use the PIN method if someone is sending a request to the server while someone else is entering the ping the server will not accept it because it will wait for a different kind of message. As a result it will be as if the card isn't valid even though it is. What you can do though is that you set up a "mini-server" under each store where data will be picked up and sent one by one. Maybe each server communicates with each other? Anyway its up to you. But you will basically need to set each request in an order and send them 1 by 1 to the server so that the transactions happen correctly.
Posted 18 August 2014 - 03:27 AM
Why not just set up an encryption system at the tellers, if someone tried to change or duplicate the card, they won't know how to I am currently working on one right now….. But the duplication problem I am sorta having troubles stopping…..